微軟網站上有一篇 MMC Snap-in 的入門教學文章:How-To Create a Hello World Snap-in。這份文件在當時已經蠻清楚了,只是後來沒有持續更新,以至於有些內容未跟上目前的作業環境。這裡就針對過時或未及之處做一些補充,包括 MMC 3.0 執行於 64 位元環境的問題,以及與 .NET 4 的相容性問題。
加入組件
首先,該文直接切入程式碼撰寫的部分,遺漏了加入組件的動作。你必須為你的 DLL 專案加入下列組件參考:
安全原則
然後,文中提到要為你的組件套用以下 attribute:
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Unrestricted = true)]
如果你的目標平台是 .NET 4,上面那行就不用了,寫了反而會出現編譯警告。因為從 .NET 4 開始,SecurityAction 中定義的各種要求權限的動作已被標示為過時,不該再使用了。而且,就算你在 .NET 4 程式中使用這些要求,它們也沒有任何實質作用。如官方文件所說的:
MMC 運行 .NET 4 組件會有問題,這個稍後會說明。
程式碼的部分,照抄範例就行。寫好之後,接著進行安裝。
安裝
以 Administrator 身分開啟「命令提示字元」,然後輸入:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil -i 你的組件.dll
如果是作業系統是 64 位元,則必須改用以下命令:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil -i 你的組件.dll
這樣才會使用正確版本的 InstallUtil,也才能夠將組件的 registry 資訊寫入正確的位置。
如果電腦上有安裝 Visual Studio,也可以直接用系統管理員身分開啟 Visual Studio Command Prompt--它一樣有區分 x86 和 x64 版本,請依你的作業環境選擇對應的版本(原因同上)。
安裝成功的畫面:
開啟 regedit,查看剛才加入的 registry key,位置是:HKLM/Software/Microsoft/MMC/SnapIns。參考下圖,registry key 前面多出來的 "FX:" 代表這個 MMC snapin 是個 managed 組件 。
請注意,在 64 位元的 Windows 作業系統上,如果你用 32 位元版本的 InstallUtil 來安裝組件,那麼組件的註冊資訊就不是寫入至上述位置,而是這裡:HKLM\Software\Wow6432Node\Microsoft\MMC\SnapIns。而且,在稍後進行測試時,你會發現 MMC console 不會列出你的 snapin。這個部分稍後會再進一步說明。
測試
安裝完成後,接著就來測試看看。
執行 mmc。然後從主選單點選「檔案 > 新增/移除嵌入式管理單元」,接著應該可以在左邊清單裡找到你的 snapin,如下圖:
如果找不到你的 snapin,那就很可能是先前的註冊動作失敗,或者你的作業系統是 64 位元,在註冊時卻使用了 32 位元版本的 InstallUtil。
如果想要以 32 位元的方式來註冊和執行你的 MMC snapin 也可以,只要在執行 mmc 時加入參數 "-32",如下:
mmc -32
把 snapin 加入 MMC 之後,就可以看到我們寫的 snapin 了。如下圖:
.NET 4 相容性
預設情況下,MMC 3.0 只支援 CLR 2 的組件,所以如果將 snap-in 專案的 target framework 設定為 .NET 4,當 MMC 載入此 snap-in 時,便會出現如下錯誤:
不過,同一個 Hello Snap-in 程式,在 64 位元 Windows 2008 上面用 MMC 載入執行時會出錯,放到 64 位元的 Windows 8 上面跑卻沒問題。看起來,Windows 8 的 MMC 已經可以正確執行以 .NET 4 編譯的 snap-in 了。
如果你也碰到上述問題,但仍想用或不得不用 .NET 4 來編譯你的 snap-in 專案,還是有辦法解決:在 Windows/System32 目錄下找到 mmc.exe,在此資料夾下新建一個文字檔,取名叫 mmc.exe.config,然後將底下的文字貼上去:
我試的結果是不會再出現 BadImageFormatException 的錯誤。
延伸閱讀
加入組件
首先,該文直接切入程式碼撰寫的部分,遺漏了加入組件的動作。你必須為你的 DLL 專案加入下列組件參考:
- Microsoft.ManagementConsole - 組件所在位置:c:\Windows\assembly\GAC_MSIL\
- System.Configuration.Install
安全原則
然後,文中提到要為你的組件套用以下 attribute:
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Unrestricted = true)]
如果你的目標平台是 .NET 4,上面那行就不用了,寫了反而會出現編譯警告。因為從 .NET 4 開始,SecurityAction 中定義的各種要求權限的動作已被標示為過時,不該再使用了。而且,就算你在 .NET 4 程式中使用這些要求,它們也沒有任何實質作用。如官方文件所說的:
The .NET Framework 4 removes runtime enforcement of these enumeration values. Assemblies containing the attributes that use these SecurityAction values will continue to load; however, the CLR will not refuse to load the referenced assemblies or modify their grant set based upon the permission sets.
MMC 運行 .NET 4 組件會有問題,這個稍後會說明。
程式碼的部分,照抄範例就行。寫好之後,接著進行安裝。
安裝
以 Administrator 身分開啟「命令提示字元」,然後輸入:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil -i 你的組件.dll
如果是作業系統是 64 位元,則必須改用以下命令:
c:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil -i 你的組件.dll
這樣才會使用正確版本的 InstallUtil,也才能夠將組件的 registry 資訊寫入正確的位置。
如果電腦上有安裝 Visual Studio,也可以直接用系統管理員身分開啟 Visual Studio Command Prompt--它一樣有區分 x86 和 x64 版本,請依你的作業環境選擇對應的版本(原因同上)。
Note: 如果沒有用系統管理員的身分來開啟這個命令視窗,可能會出現權限不足的錯誤(因為需要寫入 registry)。
安裝成功的畫面:
開啟 regedit,查看剛才加入的 registry key,位置是:HKLM/Software/Microsoft/MMC/SnapIns。參考下圖,registry key 前面多出來的 "FX:" 代表這個 MMC snapin 是個 managed 組件 。
測試
安裝完成後,接著就來測試看看。
執行 mmc。然後從主選單點選「檔案 > 新增/移除嵌入式管理單元」,接著應該可以在左邊清單裡找到你的 snapin,如下圖:
如果找不到你的 snapin,那就很可能是先前的註冊動作失敗,或者你的作業系統是 64 位元,在註冊時卻使用了 32 位元版本的 InstallUtil。
如果想要以 32 位元的方式來註冊和執行你的 MMC snapin 也可以,只要在執行 mmc 時加入參數 "-32",如下:
mmc -32
把 snapin 加入 MMC 之後,就可以看到我們寫的 snapin 了。如下圖:
.NET 4 相容性
預設情況下,MMC 3.0 只支援 CLR 2 的組件,所以如果將 snap-in 專案的 target framework 設定為 .NET 4,當 MMC 載入此 snap-in 時,便會出現如下錯誤:
MMC 3.0 載入 .NET 4 的 snap-in 組件時會發生錯誤 |
不過,同一個 Hello Snap-in 程式,在 64 位元 Windows 2008 上面用 MMC 載入執行時會出錯,放到 64 位元的 Windows 8 上面跑卻沒問題。看起來,Windows 8 的 MMC 已經可以正確執行以 .NET 4 編譯的 snap-in 了。
如果你也碰到上述問題,但仍想用或不得不用 .NET 4 來編譯你的 snap-in 專案,還是有辦法解決:在 Windows/System32 目錄下找到 mmc.exe,在此資料夾下新建一個文字檔,取名叫 mmc.exe.config,然後將底下的文字貼上去:
<?xml version="1.0" encoding="UTF-8"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> <requiredRuntime version="v4.0.20506" /> </startup> </configuration>
我試的結果是不會再出現 BadImageFormatException 的錯誤。
延伸閱讀
- MSDN: Developing with Microsoft Management Console (挺不錯的入門教學)
- MSDN: Running 32-bit and 64-bit Snap-ins in 64-bit Windows
- MS Connect: Can not use .Net 4.0 to create MMC SnapIn
沒有留言: