The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

用 .NET 寫 COM 元件的注意事項

之前曾經接了一個案子,需要寫一個元件給 ASP 來呼叫,我最後是採用 .NET 開發出相關功能,然後設定成一個 COM 元件,而當時也有紀錄下整個開發的過程,如下:

1. 開啟 Visual Studio 2005

2. 新增 Class Library 專案

3. 要在專案屬性中的 Build 頁籤勾選 Register for COM interop

4. 註冊 COM 的 Module 名稱為 Class 的 [Namespace].[ClassName]

5. 類別(Class)要引入 System.Runtime.InteropServices 命名空間

using System.Runtime.InteropServices;

6. 在類別定義的地方要加上 [ComVisible(true)] 屬性

以下是一個完整的範例程式:

using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices; 

namespace Miniasp
{
    [ComVisible(true)]
    public class MyFirstCOM
    {
        private string _ErrorMsg; 

        public string ErrorMsg
        {
            get { return _ErrorMsg; }
            set { _ErrorMsg = value; }
        } 

        private int _ErrorNo; 

        public int ErrorNo
        {
            get { return _ErrorNo; }
            set { _ErrorNo = value; }
        } 

        /// <summary>
        /// Applies the domain.
        /// </summary>
        /// <param name="Email">The email.</param>
        /// <param name="DomainName">Name of the domain.</param>
        public void ApplyDomain(string Email, string DomainName)
        {
            throw new System.NotImplementedException();
        } 

        /// <summary>
        /// Removes the domain.
        /// </summary>
        /// <param name="DomainName">Name of the domain.</param>
        public void RemoveDomain(string DomainName)
        {
            throw new System.NotImplementedException();
        }
    }
}

就這麼簡單,接下來就是如何部署的問題了,若要手動部署 .NET 所寫的 COM 元件,可以參考 MSDN 上的這篇文章:部署 Interop 應用程式

以下是我的一些摘要筆記:

1. 手動註冊 COM interop 的指令

gacutil /i MyFirstCOM.dll
Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb /register

2. 手動取消註冊 Interop 的指令

Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb /unregister

注意:當你註冊 COM 元件成功後,每次在 IIS 執行測試 COM 元件的 ASP 程式後,只要 COM 元件有更新並重新註冊後,都要重新啟動 IIS 或 W3SVC 才會真正生效。你可以執行 iisreset 指令完成 IIS 的重新啟動作業。

iisreset

而若要能自動執行部署工作的話,可以使用 Windows Installer 進行 .NET COM 元件的部署,你可以參考 MSDN 上的這篇文章:Windows Installer 部署疑難排解 學習相關知識。不過因為牽扯到要註冊元件的動作,所以除了將檔案安裝到主機外,我當時還另外寫了兩支 VBScript 程式用來做元件註冊與解除安裝時所需的取消註冊動作。

以下是安裝完成後所需的 VBScript 程式,用以註冊元件:

'PostInstall_RegisterCOM.vbs
'@rem c:
'@rem cd "C:\Program Files\Miniasp\MyFirstCOM" 

Set WshShell = CreateObject("WScript.Shell") 

'這裡的 Property("CustomActionData") 是透過 Windows Installer 傳遞過來的參數
WshShell.CurrentDirectory = Property("CustomActionData") 
'顯示目前的所在目錄(除錯用)
'WScript.Echo WshShell.CurrentDirectory 

WshShell.Run "net stop w3svc",7,True 

WshShell.Run "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb"            ,7,True
WshShell.Run "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb /unregister",7,True
WshShell.Run "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb /register"  ,7,True
WshShell.Run "gacutil /i MyFirstCOM.dll" & """"  ,7,True 

WshShell.Run "net start w3svc",7,True 

Set WshShell = Nothing

以下是解除安裝時所需的 VBScript 程式:

'PostUninstall_UnregisterCOM.vbs
'@rem c:
'@rem cd "C:\Program Files\Miniasp\MyFirstCOM" 

Set WshShell = CreateObject("WScript.Shell") 

WshShell.CurrentDirectory = Property("CustomActionData") 

WshShell.Run "net stop w3svc",7,True 

WshShell.Run "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Regasm.exe MyFirstCOM.dll /tlb:MyFirstCOM.tlb /unregister" ,7,True
WshShell.Run "gacutil /u MyFirstCOM.dll",7,True 

Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile "MyFirstCOM.tlb" 

WshShell.Run "net start w3svc",7,True 

Set WshShell = Nothing

最後就是要製作 Windows 安裝程式了:

首先,必須設定 [自訂動作]

  • Commit
    • PostInstall_RegisterCOM.vbs
  • Rollback
    • PostUninstall_UnregisterCOM.vbs
  • Uninstall
    • PostUninstall_UnregisterCOM.vbs

然後要在每一個 [自訂動作] 的屬性視窗編輯 [CustomActionData] 屬性,並輸入:

[TARGETDIR]

這樣就大功告成了!

接下來就是如何在 ASP 程式裡呼叫我們用 .NET 寫的 COM 元件了,底下是一個簡單的範例:

<%
Set Obj = Server.CreateObject("Miniasp.MyFirstCOM")

Obj.ApplyDomain Email, DomainName

If Obj.ErrorNo = 0 Then
    Response.Write("新增成功!")
Else
    Response.Write("新增失敗:" & Obj.ErrorMsg)
End If

Obj.RemoveDomain DomainName
%>

重申一次:只要在 IIS 執行過測試 COM 元件的 ASP 程式,只要 COM 元件有更新並重新註冊後,都要重新啟動 IIS 或 W3SVC 才會真正生效。你可以執行 iisreset 指令完成 IIS 的重新啟動作業。

相關連結