SQL DMO Error: System.Runtime.InteropServices.COMException - [SQL-DMO]The passed object is not a SQLDMO object.

Hi Experts,

I encountering a strange problem (for a change!), when attempting to perfom a SQL Backup using the SQL-DMO objects.

First of all, I must state that I AM able to perform the backup using SQL-DMO, if I instantiate a SQLServer2 object, Connect, and then instantiate a SqlBackup2 object and call SQLBackup Method.
The above works fine without any error.

I then had the (perhaps crazy) idea of creating a couple of user controls to provide the functionality to connect to a SQL Server and perform a backup of a database on that server.

I created 2 user controls: SqlServerConnector & SqlServerBackup.

The first control is used to establish a connection to a SQL Server.

The connected server object (of type SQLDMO.SqlServer2) is then passed to the SqlServerBackup object (via a property).

The second control then uses the passed server object to populate a combo with the available databases on that server (everything working fine up to here).

This second control contains a button, which when pressed prompts for a backup file location and name, and finally calls the SqlBackup method of the SqlBackup2 object, passing it the SqlServer2 object which was connected earlier.

It is at this point that I get the following exception:
System.Runtime.InteropServices.COMException - [SQL-DMO]The passed object is not a SQLDMO object.

I am miffed as to why this is happening, as when I follow the exact same procedure using objects local to a procedure it all works fine.

This indicates to me that the problem is somehow related to storing the object in a property.... but I don't know how or why.

Furthermore, the exception is thrown instantly (unlike in usual scenarios where - when stepping through - there is a slight pause before it goes into the Catch block).

Does anyone out there have any idea what might be causing this, it's starting too really bug me now!!!

Thanks in advance,

David  :o)
LVL 8
doobdaveAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
David,

I am game ;)  Are you passing a UserControl or an SQL-DMO COM object?

Bob
0
doobdaveAuthor Commented:
Hiya Bob!

to clarify, the SqlServerBackup (UserControl) has a property called ConnectedServer, which is of type SQLDMO.SQLServer2 (which is a SQL-DMO object).

This is set by the form which hosts both the SqlServerConnnector (UserControl) and the SqlServerBackup (UserControl).

The puzzling thing is: in the SqlServerBackup UserControl, I populate the Databases combobox in the Set of the ConnectedServer property, as follows:


 Public Property ConnectedServer() As SQLDMO.SQLServer2
        Get
            Return objConnectedServer
        End Get
        Set(ByVal Value As SQLDMO.SQLServer2)

            objConnectedServer = Value

            PopulateDatabases()

        End Set
    End Property

 Public Sub PopulateDatabases()

        Try
            If Not IsNothing(objConnectedServer) Then
               
                ' First, clear the combo box.
                cboDatabases.Items.Clear()

                For Each objDb As SQLDMO.Database2 In objConnectedServer.Databases
                    cboDatabases.Items.Add(objDb.Name)
                Next

                cboDatabases.SelectedIndex = 0

            End If

        Catch ex As Exception
            Trace.WriteLine(ex.ToString)
            Trace.Flush()
        End Try


And the databases combo gets populated ok, leading me to believe that there's nothing wrong with the ConnectedServer object itself..... but I'm probably wrong.

Any ideas or suggestions would be greatly appreciated.

David
0
Bob LearnedCommented:
>>It is at this point that I get the following exception:
>>System.Runtime.InteropServices.COMException - [SQL-DMO]The passed object is not a SQLDMO object.
What point?

Bob
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

doobdaveAuthor Commented:
Sorry, I didn't include that code:

    Private Sub DoBackup()

        Try
            ' Reset the progress bar.
            If Not IsNothing(pbProgress) Then
                pbProgress.Value = 0
            End If

            objBackup.Files = Me.BackupFilePath
            objBackup.Database = cboDatabases.Text
            objBackup.PercentCompleteNotification = 1

            objBackup.SQLBackup(Me.ConnectedServer)    ' <<< This is the problematic line!


        Catch ComEx As System.Runtime.InteropServices.COMException
            Trace.WriteLine(ComEx.ToString)
            Trace.Flush()

        Catch ex As Exception
            Trace.WriteLine(ex.ToString)
            Trace.Flush()

        Finally

        End Try

    End Sub
0
Bob LearnedCommented:
How is this defined?

    objBackup.SQLBackup

Bob
0
doobdaveAuthor Commented:
Private WithEvents objBackup As New SQLDMO.Backup2
0
Bob LearnedCommented:
>>First of all, I must state that I AM able to perform the backup using SQL-DMO, if I instantiate a SQLServer2 object, >>Connect, and then instantiate a SqlBackup2 object and call SQLBackup Method.
>>The above works fine without any error.
Do you still have this code, for a comparison?

I still don't see anything that would explain that error.

Another thing to check:

   How is the ConnectedServer property set?

Bob
0
doobdaveAuthor Commented:
Yep, this is the code that works:

  Dim objserver As SQLDMO.SQLServer2
        Dim objbackup As SQLDMO.Backup2

        Try
            objserver = New SQLDMO.SQLServer2
            objserver.LoginSecure = True
            objserver.Connect("myservername")

            objbackup = New SQLDMO.Backup2

            objbackup.Database = "northwind"
            objbackup.Files = "C:\test.bak"
            objbackup.SQLBackup(objserver)


        Catch ex As Exception
            Trace.WriteLine(ex.ToString)
            Trace.Flush()
        End Try

Whereas in the non-functioning code, the ConnectedServer property is set as follows:
objSqlServerBackup.ConnectedServer = objSqlServerConnector.ConnectedServer

And, before you ask, this is how the ConnectedServer property is defined in the SqlServerConnector UserControl:

 Private WithEvents objConnectedServer As SQLDMO.SQLServer2

Public ReadOnly Property ConnectedServer() As SQLDMO.SQLServer2
        Get
            Return objConnectedServer
        End Get
    End Property


I wonder, given these code snippets, if you are able to replicate the exception?

David
0
Bob LearnedCommented:
I have Oracle here, and SQL Server at home, so I can't test until later.  It seems like you have taken something straight forward, and turned it into a monster. *BIG GRIN*

Bob
0
doobdaveAuthor Commented:
Bob,

Do you think that I am over-complicating things with this UserControl approach?

My idea was to create re-usable controls that I could drop into other apps whenever I needed to, say, make a connection to SQL Server.

Do you have any suggestions as to how I might improve/simplify the design, or am I going down totally the wrong track?

David
0
Bob LearnedCommented:
Giving only 3 to 5 seconds of thought to this problem, my first impression would be to create a simple UserControl that takes your simple code, and extends it with properties:

Public Property LoginSecure() As Boolean
Public Property ServerName() As String
Public Property Database() As String
Public Property Files() As String

Public Sub DoBackup()
   
    ' Validate property conditions, such as ServerName.Length > 0, Database.Length > 0, and Files.Length > 0

    Try

        Dim objserver As SQLDMO.SQLServer2
        Dim objbackup As SQLDMO.Backup2

        objserver = New SQLDMO.SQLServer2
        objserver.LoginSecure = Me.LoginSecure
        objserver.Connect(Me.ServerName)

        objbackup = New SQLDMO.Backup2

        objbackup.Database = Me.Database
        objbackup.Files = Me.Files
        objbackup.SQLBackup(objserver)

     Catch ex As Exception
          Trace.WriteLine(ex.ToString)
          Trace.Flush()
        End Try

End Sub

It is clean, simple, and customizable.

Bob
0
doobdaveAuthor Commented:
That's an excellent idea Bob, however I was aiming to have a separate "Connector" control, which could be used in other applications, and for other purposes.

So that if I wanted to create a backup/restore utility, I would just drop that in, create the appropriate form, drop in the connector control, and add the backup/restore functionality (which is as far as I've got).

Perhaps I'm just making things too complicated then... Maybe I just got carried away with the idea of having re-usable controls.

It would still be good to get to the bottom of this strange error though, if possible.

David
0
doobdaveAuthor Commented:
Bob,

Did get a chance to try that out?
Were you able to reproduce the problem?

Anyone else out there come across this problem before?

David
0
Bob LearnedCommented:
No, sir, I had other fish to fry, and didn't get to your problem.  Could you by any chance email me those two classes so that I don't have to go through the motions of the reproducing the error?  My email is in my profile.

Bob
0
doobdaveAuthor Commented:
I surely can and will do shortly.

David
0
Bob LearnedCommented:
David,

Don't zip them up, just put them in the body of the email, cuz my Nazi email system will strip out any source code from a zip file, and I will get an empty file as a result.

Bob
0
doobdaveAuthor Commented:
Doh... I just sent them zipped and now read this... hold on
0
Bob LearnedCommented:
Dave, I am sorry that I didn't think of that earlier.  I was just trying to head off any problems.

Bob
0
doobdaveAuthor Commented:
No probs at all,

David
0
Bob LearnedCommented:
I have received anything yet.

Bob
0
doobdaveAuthor Commented:
Hmm, I did send it. Could it have been blocked?

Let me try again.

David
0
doobdaveAuthor Commented:
Ok I've sent it again,
let me know if you get it or not, and otherwise maybe I could send you a test email with no attachments, to see I'm using the correct address?

Thanks.

David
0
Bob LearnedCommented:
Nothing.
0
Bob LearnedCommented:
David,

Can you tell me what is under this Windows Registry key for you?

    HKEY_CLASSES_ROOT\Installer\Products

Look for products that have Microsoft SQL Server or SQL Server names.  I am interested in just the server instances, and not any tools or anything like that.

Bob
0
doobdaveAuthor Commented:
Bob,

I did a "Find" under that key for "SQL" and, along with a couple of tools (such as SQL Server Health and History tool, whatever that is), I have:
MySql Server 4.1
WinSQL

That is all under that key, I didn't come accross any instances.

Is this what you wanted?

David
0
Bob LearnedCommented:
That is what I wanted.  I am working up something that is pretty cool.  I have found that with MSDE and SQL Server Express 2005, that discovery of servers is pretty slow.  I was reading an article that talked about ways to discover them, and which version you have.  I wanted to see, though, how that same approach would work with full-blown SQL Server instances.

Bob
0
doobdaveAuthor Commented:
Ah ok.
Can I ask: were you able to reproduce the error on your system?

Also, I'm not sure I mentioned this before, but I am using SQL Server 2000.

Thanks again for looking into this, Bob, I appreciate it.

David
0
Bob LearnedCommented:
I got a chance to come up with a revised working SqlServerBackup component, but I didn't get a chance to get to the SqlServerConnector yet.  I am not exactly sure what that one does.  The SqlServerBackup made perfect sense, and I found it be very useful for me.

I assumed that you were running SQL Server, that is why I asked about the registry keys, since I didn't have a full-blown instance.

Bob
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
doobdaveAuthor Commented:
I see,

Well the SqlServerConnector on its own is not much use at all, but I was looking at it like a 'helper' component, in that I could drop it into any future DMO application where I first needed to make a connection to a given SQL Server.  This is why I split the connection logic away from the backup logic.

So if, for example I then wanted to create a customised SqlRestore component, I could use the Connector within the same form and pass it the ConnectedServer object.
Does this make sense, or is it illogical design?

David
0
doobdaveAuthor Commented:
Bob,

That solution you provided is ace!

I guess we will never know what was causing that odd error, however as the solution you provided is far more elegant and has also taught me something, I will award you full points.

Thanks for spending the time to look at it.

Should I post the final code for the components here, so that others may benefit?

Best Regards,

David
0
Bob LearnedCommented:
Dave,
Yes, posting the code would be great.  I would put up each class in a separate comment, along with with the test form in it's own comment.

Bob

0
doobdaveAuthor Commented:
Ok here goes...

Each of the following comments contains code for class.
0
doobdaveAuthor Commented:
'######################################################
'       SqlServerConnector
'######################################################
Imports System.ComponentModel

Public Enum AuthenticationMode
  Unknown
  Windows
  SqlServer
End Enum

Public Class SqlServerConnector
  Inherits Component

  Private m_application As New SQLDMO.Application
  Private WithEvents m_connectedServer As SQLDMO.SQLServer2

  Private m_isConnected As Boolean

  Private m_useWindowsAuthentication As Boolean

  Private m_lastServerMessage As SqlServerMessage

  Private m_traceListener As Diagnostics.TextWriterTraceListener
  Private m_traceFilePath As String

  <Browsable(False)> _
  Public ReadOnly Property SqlServerApplication() As SQLDMO.Application
    Get
      Return m_application
    End Get
  End Property


  <Browsable(False)> _
  Public ReadOnly Property ConnectedServer() As SQLDMO.SQLServer2
    Get
      Return m_connectedServer
    End Get
  End Property

  <Browsable(False)> _
  Public ReadOnly Property IsConnected() As Boolean
    Get
      Return m_isConnected
    End Get
  End Property

  <Browsable(False)> _
  Public ReadOnly Property LastServerMessage() As SqlServerMessage
    Get
      Return m_lastServerMessage
    End Get
  End Property

  Public Event RemoteLoginFailed(ByVal pServerMessage As SqlServerMessage)
  Public Event ServerMessage(ByVal pServerMessage As SqlServerMessage)

  Public Event CommandSent(ByVal pCommand As String)

  Public Event ConnectionStateChanged(ByVal sender As Object, ByVal e As EventArgs)

  Private m_password As String = String.Empty

  Private m_autoReconnect As Boolean = True
  <DefaultValue(True)> _
  Public Property AutoReconnect() As Boolean
    Get
      Return m_autoReconnect
    End Get
    Set(ByVal Value As Boolean)
      m_autoReconnect = Value
    End Set
  End Property

  Private m_authentication As AuthenticationMode = AuthenticationMode.Windows
  <DefaultValue(GetType(AuthenticationMode), "Windows")> _
  Public Property Authentication() As AuthenticationMode
    Get
      Return m_authentication
    End Get
    Set(ByVal Value As AuthenticationMode)
      m_authentication = Value
    End Set
  End Property

  Private m_startServer As Boolean = True
  <DefaultValue(True), Description("Get/set whether to start the server if it is stopped.")> _
  Public Property StartServerIfStopped() As Boolean
    Get
      Return m_startServer
    End Get
    Set(ByVal Value As Boolean)
      m_startServer = Value
    End Set
  End Property

  Private m_serverName As String = String.Empty

  <TypeConverter(GetType(ServerTypeConverter)), DefaultValue("")> _
   Public Property ServerName() As String
    Get
      Return m_serverName
    End Get
    Set(ByVal value As String)
      If value.Length = 0 Then
        Throw New ArgumentNullException("Server name")
      End If
      m_serverName = value
    End Set
  End Property

  Public Sub Connect()

    If Me.ServerName.Length = 0 Then
      Throw New ArgumentNullException("ServerName", "Server name not specified.")
    End If

    m_connectedServer = New SQLDMO.SQLServer2

    m_connectedServer.LoginSecure = (Me.Authentication = AuthenticationMode.Windows)
    m_connectedServer.AutoReConnect = Me.AutoReconnect

    ' -1 is the ODBC default of 60 seconds.
    m_connectedServer.LoginTimeout = -1

    If Me.Authentication = AuthenticationMode.Windows Then
      m_connectedServer.Connect(Me.ServerName)
    Else
      Dim userName, password As String
      Me.GetLoginCredentials(userName, password)
      m_connectedServer.Connect(Me.ServerName, userName, password)
    End If

    m_connectedServer.AutoStart = Me.StartServerIfStopped

    m_isConnected = True

    RaiseEvent ConnectionStateChanged(Me, EventArgs.Empty)

  End Sub

  Private Sub GetLoginCredentials(ByRef userName As String, ByRef password As String)

    Dim frmLogin As New frmLogin
    If frmLogin.ShowDialog() = DialogResult.OK Then
      userName = frmLogin.txtUserName.Text
      password = frmLogin.txtPassword.Text
    Else
      userName = String.Empty
      password = String.Empty
    End If

  End Sub 'GetLoginCredentials

  Public Sub Disconnect()

    If Not m_connectedServer Is Nothing Then
      m_connectedServer.DisConnect()
      m_connectedServer = Nothing
    End If

    m_isConnected = False

    RaiseEvent ConnectionStateChanged(Me, EventArgs.Empty)

  End Sub

  Private Function DisplayMessage(ByVal pMsg As String, ByVal pTitle As String, Optional ByVal pButtons As MessageBoxButtons = MessageBoxButtons.OK, Optional ByVal pIcon As MessageBoxIcon = MessageBoxIcon.Information) As DialogResult

    MessageBox.Show(pMsg, pTitle, pButtons, pIcon)

  End Function


  Private Sub ServerCommandSent(ByVal SQLCommand As String) Handles m_connectedServer.CommandSent

    RaiseEvent CommandSent(SQLCommand)

  End Sub


  Private Function ServerConnectionBroken(ByVal message As String) As Boolean Handles m_connectedServer.ConnectionBroken

    m_isConnected = False

    If DisplayMessage(String.Format("The connection to SQL Server was broken.{0}Reason:{0}{1}{0}{0}Do you wish to reconnect?", ControlChars.CrLf, message), "Connection to SQL Server Broken", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) = DialogResult.Yes Then

      m_isConnected = True

      Return True
    End If

    Return False

  End Function


  Private Function ServerQueryTimeout(ByVal Message As String) As Boolean Handles m_connectedServer.QueryTimeout

    If DisplayMessage(Message & vbCrLf & _
      "Do you wish to continue query execution or cancel?", "QueryTimeout Event Occurred", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) = DialogResult.OK Then

      Return True
    End If

    Return False

  End Function


  Private Sub m_connectedServer_RemoteLoginFailed(ByVal Severity As Integer, ByVal MessageNumber As Integer, ByVal MessageState As Integer, ByVal Message As String) Handles m_connectedServer.RemoteLoginFailed

    RaiseEvent RemoteLoginFailed(Me.CreateServerMessage(Severity, MessageNumber, MessageState, Message))

  End Sub


  Private Sub m_connectedServer_ServerMessage(ByVal Severity As Integer, ByVal MessageNumber As Integer, ByVal MessageState As Integer, ByVal Message As String) Handles m_connectedServer.ServerMessage

    RaiseEvent ServerMessage(Me.CreateServerMessage(Severity, MessageNumber, MessageState, Message))

  End Sub

  Private Function CreateServerMessage(ByVal severity As String, _
    ByVal number As Integer, ByVal state As Integer, ByVal message As String) As SqlServerMessage

    Dim serverMessage As New SqlServerMessage

    serverMessage.Severity = severity
    serverMessage.MessageNumber = number
    serverMessage.MessageState = state
    serverMessage.Message = message

    Return serverMessage

  End Function

  Public Overrides Function ToString() As String
    Return Me.Site.Name
  End Function

End Class
0
doobdaveAuthor Commented:
'######################################################
'       SqlServerBackup
'######################################################

Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design
Imports System.Drawing.Design
Imports System.Runtime.InteropServices
Imports SQLDMO

Public Enum BackupJobType
    WholeDatabase = SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database
    LogFiles = SQLDMO_BACKUP_TYPE.SQLDMOBackup_Log
    Differential = SQLDMO_BACKUP_TYPE.SQLDMOBackup_Differential
    DataFiles = SQLDMO_BACKUP_TYPE.SQLDMOBackup_Files
End Enum

<DefaultEvent("PercentComplete")> _
Public Class SqlServerBackup
    Inherits System.ComponentModel.Component

    Private WithEvents m_backup As New SQLDMO.Backup2

    Public Event PercentComplete(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
    Public Event NextMedia(ByVal pMessage As String)
    Public Event Complete(ByVal sender As Object, ByVal e As SqlServerBackupEventArgs)

    Private WithEvents m_connector As SqlServerConnector

    <DefaultValue(""), TypeConverter(GetType(ConnectorTypeConverter))> _
    Public Property Connector() As SqlServerConnector
        Get
            Return m_connector
        End Get
        Set(ByVal Value As SqlServerConnector)
            m_connector = Value
        End Set
    End Property

    Private m_backupFilePath As String = String.Empty

    <Editor(GetType(FolderNameEditor), GetType(UITypeEditor)), DefaultValue("")> _
    Public Property BackupFilePath() As String
        Get
            Return m_backupFilePath
        End Get
        Set(ByVal value As String)
            m_backupFilePath = value
        End Set
    End Property

    Private m_backupAction As BackupJobType

    <DefaultValue(GetType(BackupJobType), "WholeDatabase")> _
    Public Property BackupAction() As BackupJobType
        Get
            Return m_backupAction
        End Get
        Set(ByVal value As BackupJobType)
            m_backupAction = value
        End Set
    End Property

    Private m_databaseName As String = String.Empty

    <TypeConverter(GetType(DatabaseConverter)), DefaultValue("")> _
    Public Property DatabaseName() As String
        Get
            Return m_databaseName
        End Get
        Set(ByVal value As String)
            m_databaseName = value
        End Set
    End Property


    Public Sub DoBackup()

        If Me.Connector Is Nothing Then
            Throw New ArgumentNullException("ConnectorName", "Connector not selected.")
        End If

        If Me.Connector.ServerName.Length = 0 Then
            Throw New ArgumentNullException("Connector.ServerName", "Connector server name not specified.")
        End If

        If Me.BackupFilePath.Length = 0 Then
            Throw New ArgumentNullException("BackupFilePath", "Backup file path not specified.")
        End If

        If Me.DatabaseName.Length = 0 Then
            Throw New ArgumentNullException("DatabaseName", "Source database name not specified.")
        End If

        If Not Me.Connector.IsConnected Then
            Me.Connector.Connect()
        End If

        m_backup.Action = Me.BackupAction
        m_backup.Files = Me.BackupFilePath & IO.Path.DirectorySeparatorChar & Me.DatabaseName & "_" & _
               GetTimeStampString() & ".bak"
        m_backup.Database = Me.DatabaseName
        m_backup.PercentCompleteNotification = 1

        m_backup.SQLBackup(Me.Connector.ConnectedServer)

    End Sub


    Private Function GetTimeStampString() As String

        Dim dtDate As DateTime
        Dim strDate As String

        dtDate = DateTime.Now
        strDate = Replace(Replace(Replace(dtDate.ToString("u"), "-", ""), ":", ""), " ", "")

        Return strDate.Substring(0, strDate.Length - 1)

    End Function


    Private Sub m_backup_Complete(ByVal Message As String) Handles m_backup.Complete
        RaiseEvent Complete(Me, New SqlServerBackupEventArgs(Message))
    End Sub

    Private Sub m_backup_NextMedia(ByVal Message As String) Handles m_backup.NextMedia
    End Sub

    Private Sub m_backup_PercentComplete(ByVal message As String, ByVal percent As Integer) Handles m_backup.PercentComplete
        RaiseEvent PercentComplete(Me, New PercentCompleteEventArgs(message, percent))
    End Sub

End Class
0
doobdaveAuthor Commented:
' ##################################################
'  frmLogin
' ##################################################

Public Class frmLogin
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
  Friend WithEvents lblUserName As System.Windows.Forms.Label
  Friend WithEvents txtUserName As System.Windows.Forms.TextBox
  Friend WithEvents txtPassword As System.Windows.Forms.TextBox
  Friend WithEvents lblPassword As System.Windows.Forms.Label
  Friend WithEvents btnLogin As System.Windows.Forms.Button
  Friend WithEvents btnCancel As System.Windows.Forms.Button
  <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
    Me.lblUserName = New System.Windows.Forms.Label
    Me.txtUserName = New System.Windows.Forms.TextBox
    Me.txtPassword = New System.Windows.Forms.TextBox
    Me.lblPassword = New System.Windows.Forms.Label
    Me.btnLogin = New System.Windows.Forms.Button
    Me.btnCancel = New System.Windows.Forms.Button
    Me.SuspendLayout()
    '
    'lblUserName
    '
    Me.lblUserName.AutoSize = True
    Me.lblUserName.Location = New System.Drawing.Point(12, 12)
    Me.lblUserName.Name = "lblUserName"
    Me.lblUserName.Size = New System.Drawing.Size(63, 17)
    Me.lblUserName.TabIndex = 0
    Me.lblUserName.Text = "User Name:"
    '
    'txtUserName
    '
    Me.txtUserName.Location = New System.Drawing.Point(12, 28)
    Me.txtUserName.Name = "txtUserName"
    Me.txtUserName.Size = New System.Drawing.Size(164, 21)
    Me.txtUserName.TabIndex = 1
    Me.txtUserName.Text = ""
    '
    'txtPassword
    '
    Me.txtPassword.Location = New System.Drawing.Point(12, 80)
    Me.txtPassword.Name = "txtPassword"
    Me.txtPassword.PasswordChar = Microsoft.VisualBasic.ChrW(42)
    Me.txtPassword.Size = New System.Drawing.Size(164, 21)
    Me.txtPassword.TabIndex = 3
    Me.txtPassword.Text = ""
    '
    'lblPassword
    '
    Me.lblPassword.AutoSize = True
    Me.lblPassword.Location = New System.Drawing.Point(12, 64)
    Me.lblPassword.Name = "lblPassword"
    Me.lblPassword.Size = New System.Drawing.Size(55, 17)
    Me.lblPassword.TabIndex = 2
    Me.lblPassword.Text = "Password:"
    '
    'btnLogin
    '
    Me.btnLogin.DialogResult = System.Windows.Forms.DialogResult.OK
    Me.btnLogin.Location = New System.Drawing.Point(12, 120)
    Me.btnLogin.Name = "btnLogin"
    Me.btnLogin.Size = New System.Drawing.Size(64, 28)
    Me.btnLogin.TabIndex = 4
    Me.btnLogin.Text = "&Login"
    '
    'btnCancel
    '
    Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
    Me.btnCancel.Location = New System.Drawing.Point(116, 120)
    Me.btnCancel.Name = "btnCancel"
    Me.btnCancel.Size = New System.Drawing.Size(60, 28)
    Me.btnCancel.TabIndex = 5
    Me.btnCancel.Text = "C&ancel"
    '
    'frmLogin
    '
    Me.AcceptButton = Me.btnLogin
    Me.AutoScaleBaseSize = New System.Drawing.Size(5, 14)
    Me.CancelButton = Me.btnCancel
    Me.ClientSize = New System.Drawing.Size(190, 160)
    Me.Controls.Add(Me.btnCancel)
    Me.Controls.Add(Me.btnLogin)
    Me.Controls.Add(Me.txtPassword)
    Me.Controls.Add(Me.lblPassword)
    Me.Controls.Add(Me.txtUserName)
    Me.Controls.Add(Me.lblUserName)
    Me.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
    Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
    Me.Name = "frmLogin"
    Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
    Me.Text = "Login"
    Me.ResumeLayout(False)

  End Sub

#End Region

End Class
0
doobdaveAuthor Commented:
' ########################################
' RegistrySearcher
' ########################################
Imports Microsoft.Win32

Public Class RegistrySearcher

  Public Shared Function FindSqlServerProducts() As ArrayList

    Dim list As New ArrayList

    Dim root As RegistryKey = Registry.ClassesRoot.OpenSubKey("Installer\Products")

    For Each guid As String In root.GetSubKeyNames()

      Dim keyGuid As RegistryKey = root.OpenSubKey(guid)

      Dim productName As String = keyGuid.GetValue("ProductName", "")

      If productName.StartsWith("Microsoft SQL Server Desktop Engine") Then
        list.Add("MSDE")
      End If

      If productName.StartsWith("Microsoft SQL Server 2005 Express Edition") Then
        list.Add("SQLEXPRESS")
      End If

    Next guid

    Return list

  End Function

End Class
0
doobdaveAuthor Commented:
'##############################
' SqlServerMessage
'##############################

Public Class SqlServerMessage

  Private m_severity As Integer
  Private m_messageNumber As Integer
  Private m_messageState As Integer

  Public Property Severity() As Integer
    Get
      Return m_severity
    End Get
    Set(ByVal Value As Integer)
      m_severity = Value
    End Set
  End Property

  Public Property MessageNumber() As Integer
    Get
      Return m_messageNumber
    End Get
    Set(ByVal Value As Integer)
      m_messageNumber = Value
    End Set
  End Property

  Public Property MessageState() As Integer
    Get
      Return m_messageState
    End Get
    Set(ByVal Value As Integer)
      m_messageState = Value
    End Set
  End Property

  Private m_message As String
  Public Property Message() As String
    Get
      Return m_message
    End Get
    Set(ByVal Value As String)
      m_message = Value
    End Set
  End Property

End Class
0
doobdaveAuthor Commented:
'##############################
'   PercentCompleteEventArgs
'##############################
Public Class PercentCompleteEventArgs
  Inherits EventArgs

  Public Sub New(ByVal message As String, ByVal percent As Integer)
    m_message = message
    m_percent = percent
  End Sub

  Private m_message As String
  Public ReadOnly Property Message() As String
    Get
      Return m_message
    End Get
  End Property

  Private m_percent As Integer
  Public ReadOnly Property Percent() As Integer
    Get
      Return m_percent
    End Get
  End Property

End Class
0
doobdaveAuthor Commented:
'###########################
'   SqlServerBackupEventArgs
'###########################
Public Class SqlServerBackupEventArgs
  Inherits EventArgs

  Public Sub New(ByVal message As String)
    m_message = message
  End Sub

  Private m_message As String
  Public ReadOnly Property Message() As String
    Get
      Return m_message
    End Get
  End Property

End Class
0
doobdaveAuthor Commented:
'################################
'   ConnectorTypeConverter
'################################
Imports System.ComponentModel
Imports System.ComponentModel.Design.Serialization
Imports System.Globalization

Public Class ConnectorTypeConverter
  Inherits TypeConverter

  Public Overloads Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
    If (sourceType.Equals(GetType(String))) Then
      Return True
    Else
      Return MyBase.CanConvertFrom(context, sourceType)
    End If
  End Function

  Public Overloads Overrides Function ConvertTo(ByVal context As _
      ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, _
      ByVal value As Object, ByVal destType As Type) As Object

    If destType Is GetType(InstanceDescriptor) Then
      Dim ci As System.Reflection.ConstructorInfo = _
      GetType(SqlServerConnector).GetConstructor(System.Type.EmptyTypes)
      Return New InstanceDescriptor(ci, Nothing, False)
    End If
    Return MyBase.ConvertTo(context, culture, value, destType)
  End Function

  Public Overloads Overrides Function CanConvertTo( _
       ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean

    If (destinationType.Equals(GetType(InstanceDescriptor))) Then
      Return True
    Else
      Return MyBase.CanConvertTo(context, destinationType)
    End If
  End Function

  Public Overloads Overrides Function ConvertFrom( _
       ByVal context As ITypeDescriptorContext, _
       ByVal cultureInfo As CultureInfo, _
       ByVal value As Object) As Object

    If TypeOf value Is String Then
      Return CType(context.Container.Components(value.ToString), SqlServerConnector)
    Else
      Return MyBase.ConvertFrom(context, cultureInfo, value)
    End If
  End Function

  Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection

    Dim listConnectors As New ArrayList

    For Each obj As Object In context.Container.Components
      If TypeOf obj Is SqlServerConnector Then
        listConnectors.Add(CType(obj, Component).Site.Name)
      End If
    Next

    Return New StandardValuesCollection(listConnectors)

  End Function

  Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
    Return True
  End Function

End Class
0
doobdaveAuthor Commented:
'##########################
'    DatabaseConverter
'##########################
Imports System.ComponentModel
Imports System.Globalization

Public Class DatabaseConverter
  Inherits TypeConverter

  Public Overloads Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
    If (sourceType.Equals(GetType(String))) Then
      Return True
    Else
      Return MyBase.CanConvertFrom(context, sourceType)
    End If
  End Function

  Public Overloads Overrides Function ConvertTo( _
       ByVal context As ITypeDescriptorContext, _
       ByVal cultureInfo As CultureInfo, ByVal value As Object, _
       ByVal destinationType As Type) As Object

    If (destinationType.Equals(GetType(String))) Then
      Return value.ToString()
    Else
      Return MyBase.ConvertTo(context, cultureInfo, value, destinationType)
    End If
  End Function

  Public Overloads Overrides Function CanConvertTo( _
       ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean

    If (destinationType.Equals(GetType(String))) Then
      Return True
    Else
      Return MyBase.CanConvertTo(context, destinationType)
    End If
  End Function

  Public Overloads Overrides Function ConvertFrom( _
       ByVal context As ITypeDescriptorContext, _
       ByVal cultureInfo As CultureInfo, _
       ByVal value As Object) As Object

    If TypeOf value Is String Then
      Return CType(value, String)
    Else
      Return MyBase.ConvertFrom(context, cultureInfo, value)
    End If
  End Function

  Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection

    Try

      Cursor.Current = Cursors.WaitCursor

      Application.DoEvents()

      Dim backup As SqlServerBackup = CType(context.Instance, SqlServerBackup)
      Dim list As New ArrayList
      For Each database As SQLDMO.Database2 In backup.Connector.ConnectedServer.Databases
        list.Add(database.Name)
      Next

      Return New StandardValuesCollection(list)

    Catch ex As Exception

      MessageBox.Show(ex.ToString)

    Finally

      Cursor.Current = Cursors.WaitCursor

    End Try

  End Function

  Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
    Return True
  End Function

End Class
0
doobdaveAuthor Commented:
'##############################
'   ServerTypeConverter
'##############################
Imports System.ComponentModel
Imports System.Globalization

Public Class ServerTypeConverter
  Inherits TypeConverter

  Public Overloads Overrides Function CanConvertFrom(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal sourceType As System.Type) As Boolean
    If (sourceType.Equals(GetType(String))) Then
      Return True
    Else
      Return MyBase.CanConvertFrom(context, sourceType)
    End If
  End Function

  Public Overloads Overrides Function ConvertTo( _
       ByVal context As ITypeDescriptorContext, _
       ByVal cultureInfo As CultureInfo, ByVal value As Object, _
       ByVal destinationType As Type) As Object

    If (destinationType.Equals(GetType(String))) Then
      Return value.ToString()
    Else
      Return MyBase.ConvertTo(context, cultureInfo, value, destinationType)
    End If
  End Function

  Public Overloads Overrides Function CanConvertTo( _
       ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean

    If (destinationType.Equals(GetType(String))) Then
      Return True
    Else
      Return MyBase.CanConvertTo(context, destinationType)
    End If
  End Function

  Public Overloads Overrides Function ConvertFrom( _
       ByVal context As ITypeDescriptorContext, _
       ByVal cultureInfo As CultureInfo, _
       ByVal value As Object) As Object

    If TypeOf value Is String Then
      Return CType(value, String)
    Else
      Return MyBase.ConvertFrom(context, cultureInfo, value)
    End If
  End Function

  Public Overloads Overrides Function GetStandardValues(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.ComponentModel.TypeConverter.StandardValuesCollection

    Try

      Cursor.Current = Cursors.WaitCursor

      Application.DoEvents()

      Dim installedProducts As ArrayList = RegistrySearcher.FindSqlServerProducts()

      If Not installedProducts.Contains("MSDE") AndAlso _
         Not installedProducts.Contains("SQLEXPRESS") Then

        Dim listServers As New ArrayList

        Dim appSql As New SQLDMO.Application
        For Each name As String In appSql.ListAvailableSQLServers()
          listServers.Add(name)
        Next
        Return New StandardValuesCollection(listServers)
      Else
        Return New StandardValuesCollection(installedProducts)
      End If


    Catch ex As Exception

      MessageBox.Show(ex.ToString)

    Finally

      Cursor.Current = Cursors.WaitCursor

    End Try

  End Function

  Public Overloads Overrides Function GetStandardValuesSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
    Return True
  End Function

End Class
0
doobdaveAuthor Commented:
'##############################
' The test form
'##############################
Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents SqlServerConnector1 As SqlDataManagementObjects.SqlServerConnector
    Friend WithEvents SqlServerBackup1 As SqlDataManagementObjects.SqlServerBackup
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.SqlServerConnector1 = New SqlDataManagementObjects.SqlServerConnector
        Me.SqlServerBackup1 = New SqlDataManagementObjects.SqlServerBackup
        Me.Button1 = New System.Windows.Forms.Button
        Me.ComboBox1 = New System.Windows.Forms.ComboBox
        Me.SuspendLayout()
        '
        'SqlServerConnector1
        '
        Me.SqlServerConnector1.ServerName = "(local)"
        '
        'SqlServerBackup1
        '
        Me.SqlServerBackup1.BackupFilePath = "C:\"
        Me.SqlServerBackup1.Connector = Me.SqlServerConnector1
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(24, 168)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(240, 23)
        Me.Button1.TabIndex = 0
        Me.Button1.Text = "Button1"
        '
        'ComboBox1
        '
        Me.ComboBox1.Location = New System.Drawing.Point(32, 48)
        Me.ComboBox1.Name = "ComboBox1"
        Me.ComboBox1.Size = New System.Drawing.Size(192, 21)
        Me.ComboBox1.TabIndex = 1
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Controls.Add(Me.ComboBox1)
        Me.Controls.Add(Me.Button1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


Dim objserver As SQLDMO.SQLServer2
    Dim objbackup As SQLDMO.Backup2

    Try
      objserver = New SQLDMO.SQLServer2
      objserver.LoginSecure = True
      objserver.Connect("learned")

      objbackup = New SQLDMO.Backup2

      objbackup.Database = "couples"
      objbackup.Files = "C:\test.bak"
      objbackup.SQLBackup(objserver)

      objserver.DisConnect()

    Catch ex As Exception
      Trace.WriteLine(ex.ToString)
      Stop
    End Try


    End Sub
End Class
0
doobdaveAuthor Commented:
Hope I haven't missed anything out, and hope this helps somebody.

Thanks again Bob for your help on this.

Best Regards,

David
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.