SQL Server 2000 DTS (Data Transformation Services) 支持 COM 介面擴展自定義任務。雖然 DTS 已被 SSIS 取代,但存量系統維護仍需此技能。本文完整記錄:RCW 生成、強名簽名、GAC 安裝、COM 註冊/反註冊、CustomTask 介面實現、屬性/集合/Execute 方法、UI 整合、部署腳本。
dtspkg.dll (COM 類型庫)tlbimp.exe、sn.exe、gacutil.exe、guidgen.exerem 1. 生成強名金鑰
sn.exe -k DTSPkg.snk
rem 2. 導入類型庫生成 RCW (Microsoft.SQLServer.DTSPkg80.dll)
tlbimp.exe "C:\Program Files\Microsoft SQL Server\80\Tools\Binn\dtspkg.dll" ^
/out:Microsoft.SQLServer.DTSPkg80.dll ^
/keyfile:DTSPkg.snk ^
/namespace:Microsoft.SQLServer.DTSPkg80
rem 3. 安裝到 GAC
gacutil.exe /i Microsoft.SQLServer.DTSPkg80.dll
Microsoft.SQLServer.DTSPkg80.dll[assembly: ClassInterface(ClassInterfaceType.AutoDual)]using System;
using System.Runtime.InteropServices;
using Microsoft.SQLServer.DTSPkg80;
using Microsoft.Win32;
using System.Windows.Forms;
namespace DTS.CustomTasks
{
[Guid("38ED4F80-9EF4-4752-8478-65D2DB3BA7DD")]
[ComVisible(true)]
[ProgId("DTS.SimpleCustomTask")]
[ClassInterface(ClassInterfaceType.AutoDual)]
public class SimpleCustomTask : CustomTask
{
private string _name = "";
private string _description = "SimpleCustomTask description";
// 必須實現:CustomTask 介面成員
public string Name
{
get => _name;
set => _name = value;
}
public string Description
{
get => _description;
set => _description = value;
}
public Properties Properties => null; // 無自定義屬性集,設計器將使用默認屬性網格
public void Execute(object pPackage, object pPackageEvents, object pPackageLog, ref DTSTaskExecResult pTaskResult)
{
pTaskResult = DTSTaskExecResult.DTSTaskExecResult_Failure; // 預設失敗
try
{
var pkg = (Package2)pPackage;
var events = (PackageEvents)pPackageEvents;
var log = (PackageLog)pPackageLog;
MessageBox.Show(_description); // 示例:彈窗顯示描述
// 實際業務:ETL 轉換、文件操作、數據庫腳本執行等
pTaskResult = DTSTaskExecResult.DTSTaskExecResult_Success;
}
catch (COMException ex)
{
Console.WriteLine($"COM 異常: {ex}");
}
catch (Exception ex)
{
Console.WriteLine($"一般異常: {ex}");
}
}
public override string ToString() => base.ToString();
// ===== COM 註冊/反註冊 =====
[ComRegisterFunction]
public static void RegisterServer(Type t)
{
try
{
const string TASK_CACHE = @"Software\Microsoft\Microsoft SQL Server\80\DTS\Enumeration\Tasks";
const string CATID_DTS_CUSTOM_TASK = "{10020200-EB1C-11CF-AE6E-00AA004A34D5}";
string guid = "{" + t.GUID.ToString().ToUpper() + "}";
// 1. 註冊 COM 分類 (HKCR\CLSID\...\Implemented Categories\CATID)
using (var root = Registry.ClassesRoot)
using (var rk = root.OpenSubKey($@"CLSID\{guid}\Implemented Categories", true))
using (var nrk = rk.CreateSubKey(CATID_DTS_CUSTOM_TASK))
{ }
// 2. 加入 DTS 任務枚舉緩存 (HKCU\...\Tasks\{GUID})
using (var root = Registry.CurrentUser)
using (var rk = root.OpenSubKey(TASK_CACHE, true))
using (var nrk = rk.CreateSubKey(guid))
{
nrk.SetValue("", t.FullName);
}
// 3. 設置任務描述顯示在設計器工具箱
using (var root = Registry.ClassesRoot)
using (var rk = root.OpenSubKey($@"CLSID\{guid}", true))
{
var ct = new SimpleCustomTask();
rk.SetValue("DTSTaskDescription", ct.Description);
}
}
catch (Exception ex)
{
Console.WriteLine($"註冊失敗: {ex}");
}
}
[ComUnregisterFunction]
public static void UnregisterServer(Type t)
{
try
{
const string TASK_CACHE = @"Software\Microsoft\Microsoft SQL Server\80\DTS\Enumeration\Tasks";
string guid = "{" + t.GUID.ToString().ToUpper() + "}";
using (var root = Registry.CurrentUser)
using (var rk = root.OpenSubKey(TASK_CACHE, true))
{
rk.DeleteSubKey(guid, false);
}
}
catch (Exception ex)
{
Console.WriteLine($"反註冊失敗: {ex}");
}
}
}
}
rem build.bat
csc.exe /target:library /out:DTS.CustomTasks.dll ^
/reference:Microsoft.SQLServer.DTSPkg80.dll ^
/keyfile:DTSPkg.snk ^
SimpleCustomTask.cs
rem register.bat (需管理員權限)
regasm.exe /codebase DTS.CustomTasks.dll
gacutil.exe /i DTS.CustomTasks.dll
rem unregister.bat
regasm.exe /u DTS.CustomTasks.dll
gacutil.exe /u DTS.CustomTasks.dll
DTS.CustomTasks.dll實現 CustomTaskUI 介面,提供 Initialize、GetView、Delete、New 方法,返回 WinForms UserControl 作為屬性編輯頁面。本文不展開,關鍵點:
ComVisible(true)、Guid、ProgIdHKCR\CLSID\{GUID}\Implemented Categories\{CATID_DTS_CUSTOM_TASK_UI}| DTS (SQL 2000) | SSIS (SQL 2005+) |
|---|---|
| COM 介面 (CustomTask) | 托管介面 Microsoft.SqlServer.Dts.Runtime.Task |
| 註冊表註冊 | 組件部署到 GlobalAssemblyCache 或 Dts\Tasks 目錄 |
| VB6/C++ 常見 | C# 為主流 |
| 無原生調試 | Visual Studio 完整調試 |