VB.NET中处理COM事件的问题
我正在从VB.NET调用SQLDMO 8.0 COM库(使用我用tlbimp生成的PIA),以便使用完成百分比通知备份数据库:VB.NET中处理COM事件的问题,.net,sql-server,vb.net,interop,.net,Sql Server,Vb.net,Interop,我正在从VB.NET调用SQLDMO 8.0 COM库(使用我用tlbimp生成的PIA),以便使用完成百分比通知备份数据库: Dim server As SQLDMO.SQLServer = Nothing Dim backup As SQLDMO.Backup = Nothing Dim restore As SQLDMO.Restore = Nothing Dim backupAbortable As Boolean Dim restoreAbortable As Boolean Try
Dim server As SQLDMO.SQLServer = Nothing
Dim backup As SQLDMO.Backup = Nothing
Dim restore As SQLDMO.Restore = Nothing
Dim backupAbortable As Boolean
Dim restoreAbortable As Boolean
Try
server = New SQLDMO.SQLServer
server.LoginSecure = True
server.Connect(serverName)
backup = New SQLDMO.Backup
backup.Action = SQLDMO.SQLDMO_BACKUP_TYPE.SQLDMOBackup_Database
backup.BackupSetDescription = "test"
backup.BackupSetName = "test"
backup.Database = databaseName
backup.Files = TransactSqlName.Delimit(fileName)
backup.TruncateLog = SQLDMO.SQLDMO_BACKUP_LOG_TYPE.SQLDMOBackup_Log_Truncate
backup.PercentCompleteNotification = 1
AddHandler backup.PercentComplete, AddressOf OnOperationPercentComplete
AddHandler backup.NextMedia, AddressOf OnOperationNextMedia
AddHandler backup.Complete, AddressOf OnOperationComplete
backupAbortable = True
backup.SQLBackup(server)
backupAbortable = False
restore = New SQLDMO.Restore
restore.Files = backup.Files
AddHandler restore.PercentComplete, AddressOf OnOperationPercentComplete
AddHandler restore.NextMedia, AddressOf OnOperationNextMedia
AddHandler restore.Complete, AddressOf OnOperationComplete
restoreAbortable = True
restore.SQLVerify(server)
restoreAbortable = False
server.DisConnect()
Catch ex As AbortException
If backupAbortable Then
backup.Abort()
End If
If restoreAbortable Then
restore.Abort()
End If
Finally
If restore IsNot Nothing Then
RemoveHandler restore.PercentComplete, AddressOf OnOperationPercentComplete
RemoveHandler restore.NextMedia, AddressOf OnOperationNextMedia
RemoveHandler restore.Complete, AddressOf OnOperationComplete
Marshal.FinalReleaseComObject(restore)
restore = Nothing
End If
If backup IsNot Nothing Then
RemoveHandler backup.PercentComplete, AddressOf OnOperationPercentComplete
RemoveHandler backup.NextMedia, AddressOf OnOperationNextMedia
RemoveHandler backup.Complete, AddressOf OnOperationComplete
Marshal.FinalReleaseComObject(backup)
backup = Nothing
End If
If server IsNot Nothing Then
Marshal.FinalReleaseComObject(server)
server = Nothing
End If
End Try
除了事件处理程序之外,它工作得很好-只有第一个连接起来的处理程序才真正执行。我不能肯定NextMedia事件,因为它只针对磁带备份触发,但对于其他两个事件,根据AddHandler语句的顺序,我要么获取Complete事件,要么获取PercentComplete事件触发,决不能同时获取这两个事件
可能性:
有什么想法吗?这在VB.NET 2005中有效,不确定1.1 我知道你已经在COM互操作上做了大量工作,但是你能在连接之外使用信息事件吗 注意STATS=10。。这意味着每10%发送一次进度通知 这只是我一直在做的一个项目的一个片段,我希望你能从中得到你所需要的
public sub Backup()
Dim Conn As SqlClient.SqlConnection
dim theCommand as SqlClient.SQLCommand
Conn = New SqlClient.SqlConnection("Data Source=.\MyInstance;Initial Catalog=Master;Integrated Security=SSPI;")
theCommand = Conn.CreateCommand
theCommand.CommandText = "BACKUP DATABASE [MyDatabase] TO DISK = '" & mDatabasePath & "\" & Filenames.SQLBackup & "' WITH NOFORMAT, INIT, NAME = 'MyDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10"
AddHandler Conn.InfoMessage, AddressOf onSqlInfoMessage
'make sure the events are fired as they are available, instead of at the end.
Conn.FireInfoMessageEventOnUserErrors = True
Conn.Open()
theCommand.ExecuteNonQuery()
RemoveHandler Conn.InfoMessage, AddressOf onSqlInfoMessage
Conn.Close()
end sub
Private Sub onSqlInfoMessage(ByVal sender As Object, ByVal args As SqlClient.SqlInfoMessageEventArgs)
If args.Message.EndsWith("percent processed.") Then
Dim theMatch As System.Text.RegularExpressions.Match
theMatch = mRegEx.Match(args.Message)
debug.print("Progress = " & theMatch.Value.Trim)
End If
End Sub
这在VB.NET2005中有效,但不确定是否为1.1 我知道你已经在COM互操作上做了大量工作,但是你能在连接之外使用信息事件吗 注意STATS=10。。这意味着每10%发送一次进度通知 这只是我一直在做的一个项目的一个片段,我希望你能从中得到你所需要的
public sub Backup()
Dim Conn As SqlClient.SqlConnection
dim theCommand as SqlClient.SQLCommand
Conn = New SqlClient.SqlConnection("Data Source=.\MyInstance;Initial Catalog=Master;Integrated Security=SSPI;")
theCommand = Conn.CreateCommand
theCommand.CommandText = "BACKUP DATABASE [MyDatabase] TO DISK = '" & mDatabasePath & "\" & Filenames.SQLBackup & "' WITH NOFORMAT, INIT, NAME = 'MyDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10"
AddHandler Conn.InfoMessage, AddressOf onSqlInfoMessage
'make sure the events are fired as they are available, instead of at the end.
Conn.FireInfoMessageEventOnUserErrors = True
Conn.Open()
theCommand.ExecuteNonQuery()
RemoveHandler Conn.InfoMessage, AddressOf onSqlInfoMessage
Conn.Close()
end sub
Private Sub onSqlInfoMessage(ByVal sender As Object, ByVal args As SqlClient.SqlInfoMessageEventArgs)
If args.Message.EndsWith("percent processed.") Then
Dim theMatch As System.Text.RegularExpressions.Match
theMatch = mRegEx.Match(args.Message)
debug.print("Progress = " & theMatch.Value.Trim)
End If
End Sub
sqldmo.dll的文件版本为2000.85.2312.0,typelib版本为8.0。运行代码所针对的SQL Server版本可以是2000或2005。我最好去仔细检查两个版本是否有相同的行为。对不起,typelib版本是8.5。SQL 2005似乎升级了我原来的SQL 2000安装。:-)是的,两个版本上都发生了相同的行为。sqldmo.dll的文件版本是2000.85.2312.0,typelib版本是8.0。运行代码所针对的SQL Server版本可以是2000或2005。我最好去仔细检查两个版本是否有相同的行为。对不起,typelib版本是8.5。SQL 2005似乎升级了我原来的SQL 2000安装。:-)是的,两个版本都有相同的行为。谢谢Paul,我不知道FireInfoMessageEventOnUserErrors属性。这是一个比使用SQLDMO更好的解决方案,我已经将所有备份/恢复代码转换回ADO.NET。不错。:-)谢谢Paul,我不知道FireInfoMessageEventOnUserErrors属性。这是一个比使用SQLDMO更好的解决方案,我已经将所有备份/恢复代码转换回ADO.NET。不错。:-)