VB6 支持 SQL SMO 和 .Net 2.0

发布于 2024-07-07 12:56:50 字数 523 浏览 8 评论 0原文

我们正在尝试在基于 COM+ 的应用程序中从使用 SQL DMO 转向使用 SMO,因为我们正在放弃对 SQL Server 2000 的支持,并在 SQL Server 2005 之外添加对 SQL Server 2008 的支持。

我一直在阅读相关内容,发现此微软论坛上的这个特殊俏皮话:

“SMO仅在 VB/C#.Net 2005 中受支持。它需要 .Net 2.0 框架,而 VB/VC 6 中不提供该框架。”

这是真的吗? 谷歌搜索一般和谷歌搜索 stackoverflow 并没有给出明确的答案。

是否可以使用VB6实现SQL SMO?

编辑:我使用 COM 包装器来解决这个问题...请查看下面我的答案以了解更多详细信息。

We are trying to move from using SQL DMO to SMO in our COM+ based application, as we are dropping support for SQL Server 2000 and adding support for SQL Server 2008 in addition to SQL Server 2005.

I have been reading around on this, and found this particular quip on this microsoft forum:

"SMO is only supported in VB/C#.Net 2005. It requires the .Net 2.0 Framework, which isn't available in VB/VC 6."

Is it true? Googling in general and googling stackoverflow did not throw up and definitive answers.

Is it possible to implement SQL SMO using VB6?

Edit: I used a COM Wrapper to get around this... check out my answer below for some more details.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧伤慢歌 2024-07-14 12:56:50

好吧,我想出了如何做到这一点。

问题是 VB6 没有 .Net 2.0 支持,因此我们不能将 SMO 与 VB6 一起使用。

为了解决这个问题,我用 C# 编写了一个 COM 包装器,它使用 SMO 并(大部分)与我想要从 VB 应用程序中获得的功能进行一对一映射。

基本上,创建一个 C# 项目,根据需要添加 SMO 引用,在类声明上方添加以下行以使其 COM 可见:

[ComVisible(true)]

[GuidAttribute("{guid here}")]

[ClassInterface(ClassInterfaceType.AutoDual)] // <--- Not recommended, but well...

在项目属性的“构建”部分中,确保“注册 COM 互操作”框已检查。 编译并导入 VB6 应用程序,您就可以开始工作了!

与尝试将任何两个不同的系统整合在一起的情况一样,您需要对 VB6 应用程序和 C# 包装器之间传递的内容进行一些操作...但这并不太难。

如果您需要更多信息/详细信息,请发表评论。

Okay I figured out how to do this.

The problem was that VB6 has no .Net 2.0 support and hence we cannot use SMO with VB6.

To get around that, I wrote a COM wrapper in C# which uses SMO and maps (mostly) one-to-one with the kind of functionality I want from from my VB app.

Basically, Create a C# project, add the SMO references as needed, add the following lines above the class declaration to make it COM visible:

[ComVisible(true)]

[GuidAttribute("{guid here}")]

[ClassInterface(ClassInterfaceType.AutoDual)] // <--- Not recommended, but well...

In the project properties, in the "Build" section, make sure the "Register For COM Interop" box is checked. Compile and import into the VB6 app and you are in business!!

As is the case with trying to hammer any two different systems together, there will be some manipulations you will need to do with what you pass between the VB6 app and the C# Wrapper... but its not too hard.

Please comment if you need any more information/details.

游魂 2024-07-14 12:56:50

我不知道有什么方法可以通过 VB6 访问 SMO。 我同意 G Mastros 关于使用 COM/Interop 方法直接实现 .NET 代码的观点。

可以考虑的另一种选择是,您可以使用 Powershell,执行一个可以完成 .NET SMO 工作的脚本。 您仍然需要 .NET 框架(显然还有 Powershell),但它可以完成工作。 您的脚本可以采用凭据、数据库名称、备份类型等参数。

我在拥有 SQL Express(没有用于备份的 SQL 代理,如 MSDE)的客户端上经常实现这一点。 我连接了一个调用脚本并管理备份的计划任务。

如果有帮助的话,这里有一个脚本——大部分是偷来的,但我对其进行了一些修改:

param (
  [string] $ServerName,
  [string] $DatabaseName,
  [string] $Backuptype,
  [string] $BackupPath,
  [int] $NumDays
)
Get-ChildItem $BackupPath | where {$_.LastWriteTime -le (Get-Date).AddDays(-$NumDays)} | remove-item
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null
[System.IO.Directory]::CreateDirectory($BackupPath) | out-null
$srv=New-Object "Microsoft.SqlServer.Management.Smo.Server" "$servername"
$bck=new-object "Microsoft.SqlServer.Management.Smo.Backup"

if ($Backuptype -eq "FULL") 
{
$bck.Action = 'Database' 
$extenstion=".BAK" 
$text1="Full Backup"
}

if ($Backuptype -eq "TRAN") 
{
$bck.Action = 'Log' 
$bck.LogTruncation = 2
$extenstion=".TRN" 
$text1="Transactional Log Backup"
}

if ($Backuptype -eq "DIFF") 
{ 
$bck.Incremental = 1 
$extenstion=".DIFF"  
$text1="Differential Backup"
}

$fil=new-object "Microsoft.SqlServer.Management.Smo.BackupDeviceItem"
$fil.DeviceType='File'
$fil.Name=[System.IO.Path]::Combine($BackupPath, $DatabaseName+ "_"+ [DateTime]::Now.ToString("yyyy_MM_dd_HH_mm")+$extenstion)
$bck.Devices.Add($fil)
$bck.Database=$DatabaseName
$bck.SqlBackup($srv)
write-host $text1 of $Databasename done

它可以进行完整备份、差异备份和事务备份,并根据日期和时间对每个结果文件进行唯一命名,删除所有早于一定数量的文件。天。

调用它的语法是:

.\Backup.ps1 INSTANCENAME DATABASENAME FULL|TRAN|DIFF PATH DAYSTOKEEP

so...

.\Backup.ps1 SQLEXPRESS Northwind FULL C:\TempHold\Test 30
.\Backup.ps1 SQLEXPRESS Northwind TRAN C:\TempHold\Test 30
.\Backup.ps1 SQLEXPRESS Northwind DIFF C:\TempHold\Test 30

要在任务计划程序中进行计划,请传入:

powershell c:\temphold\test\backup.ps1 "SQLEXPRESS Northwind DIFF C:\TempHold\Test 30"

I don't know of a way you can get to SMO via VB6. I'd agree with G Mastros about doing a COM/Interop approach to implement .NET code directly.

An alternative to consider is that you could shell out to Powershell, executing a script that would do your .NET SMO work. You still have the pre-requisite of requiring the .NET framework (and Powershell obviously), but it would get the job done. Your script could take parameters for credentials, database name, backup type, etc.

I implement this a lot at clients who have SQL Express (no SQL Agent for backups, like MSDE). I hook up a scheduled task which invokes the script and manages their backups.

If helpful, here is a script -- largely stolen but I have modified it somewhat:

param (
  [string] $ServerName,
  [string] $DatabaseName,
  [string] $Backuptype,
  [string] $BackupPath,
  [int] $NumDays
)
Get-ChildItem $BackupPath | where {$_.LastWriteTime -le (Get-Date).AddDays(-$NumDays)} | remove-item
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null
[System.IO.Directory]::CreateDirectory($BackupPath) | out-null
$srv=New-Object "Microsoft.SqlServer.Management.Smo.Server" "$servername"
$bck=new-object "Microsoft.SqlServer.Management.Smo.Backup"

if ($Backuptype -eq "FULL") 
{
$bck.Action = 'Database' 
$extenstion=".BAK" 
$text1="Full Backup"
}

if ($Backuptype -eq "TRAN") 
{
$bck.Action = 'Log' 
$bck.LogTruncation = 2
$extenstion=".TRN" 
$text1="Transactional Log Backup"
}

if ($Backuptype -eq "DIFF") 
{ 
$bck.Incremental = 1 
$extenstion=".DIFF"  
$text1="Differential Backup"
}

$fil=new-object "Microsoft.SqlServer.Management.Smo.BackupDeviceItem"
$fil.DeviceType='File'
$fil.Name=[System.IO.Path]::Combine($BackupPath, $DatabaseName+ "_"+ [DateTime]::Now.ToString("yyyy_MM_dd_HH_mm")+$extenstion)
$bck.Devices.Add($fil)
$bck.Database=$DatabaseName
$bck.SqlBackup($srv)
write-host $text1 of $Databasename done

It can do full, differential, and transactional backups and uniquely names each resulting file based on the date and time, deleting all files older than a certain number of days.

The syntax to call it is:

.\Backup.ps1 INSTANCENAME DATABASENAME FULL|TRAN|DIFF PATH DAYSTOKEEP

so...

.\Backup.ps1 SQLEXPRESS Northwind FULL C:\TempHold\Test 30
.\Backup.ps1 SQLEXPRESS Northwind TRAN C:\TempHold\Test 30
.\Backup.ps1 SQLEXPRESS Northwind DIFF C:\TempHold\Test 30

To Schedule in Task Scheduler, pass in:

powershell c:\temphold\test\backup.ps1 "SQLEXPRESS Northwind DIFF C:\TempHold\Test 30"
不再见 2024-07-14 12:56:50

谢谢你的帖子。 它帮助我理解有一个解决方案可以使用 COM Wrapper 从 VB6 中使用 SQLSMO。 我按照您详细说明的步骤操作,但我的解决方案不起作用。 我基本上是这样做的:

using System;
using System.Collections.Generic;

使用 System.Text;
使用 System.Runtime.InteropServices;
命名空间 WrapperCOM
{

[System.Runtime.InteropServices.ComVisible(true)]

[GuidAttribute("1d93750c-7465-4a3e-88d1-5e538afe7145")]



[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
    public Class1() { }
}

}

我还为 SQLSMO 添加了以下引用:

•Microsoft.SqlServer.ConnectionInfo.dll

•Microsoft.SqlServer.Smo.dll

•Microsoft.SqlServer.Management.Sdk.Sfc.dll

•Microsoft.SqlServer.SqlEnum.dll

最后当我导入 .tlb 文件并创建如下对象后运行 VB6 -
CreateObject("COMWrapper.Class1"),失败。 它给出“运行时错误...”

请告知我在这里缺少什么...

Thanks for your post. It helps me to understand that there is a solution to use SQLSMO from VB6 using COM Wrapper. I followed the steps you detailed, but my solution doesn't work . I am doing this basically:

using System;
using System.Collections.Generic;

using System.Text;
using System.Runtime.InteropServices;
namespace WrapperCOM
{

[System.Runtime.InteropServices.ComVisible(true)]

[GuidAttribute("1d93750c-7465-4a3e-88d1-5e538afe7145")]



[ClassInterface(ClassInterfaceType.AutoDual)]
public class Class1
{
    public Class1() { }
}

}

I also added the following references for SQLSMO:

•Microsoft.SqlServer.ConnectionInfo.dll

•Microsoft.SqlServer.Smo.dll

•Microsoft.SqlServer.Management.Sdk.Sfc.dll

•Microsoft.SqlServer.SqlEnum.dll

Finally when I run the VB6 after importing the .tlb file and creating an object like this -
CreateObject("COMWrapper.Class1"), It fails. It gives "RunTime Error..."

Pls advise as to what's that I am missing here...

一曲琵琶半遮面シ 2024-07-14 12:56:50

我还没有尝试过,但您可能可以编写 vb.net 代码来与 SQL SMO 交互,然后为 vb.net 代码编写 com 包装器。 当然,您仍然需要 .net 框架才能使用它。

相反,我建议您放弃 SQL DMO 和 SQL SMO。 使用 DMO 或 SMO 所做的任何事情都可以在没有它的情况下完成。 当然,这并不容易,但是通过谷歌搜索替换代码(使用直接的 T-SQL 而不是 SQL DMO)将为您提供所需的答案。

I haven't tried it, but you could probably write vb.net code to interact with SQL SMO, and then write a com wrapper for the vb.net code. Of course, you'll still need to .net framework to use it.

Instead, I would suggest that you migrate away from SQL DMO and SQL SMO. Anything you do with DMO or SMO can be done without it. Of course, it won't be easy, but googling for replacement code (using straight T-SQL instead of SQL DMO) will provide you the answers you need.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文