The Will Will Web

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

Windows Service 新增 Installer 功能並自動開啟防火牆設定

最近正準備寫一支 Windows Service 程式,正好來分享如何讓 Windows Service 程式具有自動安裝的能力,而且若要在安裝的過程中順便開啟 Windows Firewall 的設定時 C# 程式要如何撰寫。

首先,先開啟你寫好的 Windows Service 程式進入 Designer 模式,並在空白處點選滑鼠右鍵,再選取 Add Installer 選項。

首先,先開啟你寫好的 Windows Service 程式進入 Designer 模式,並在空白處點選滑鼠右鍵,再選取 Add Installer 選項。

接著,Visual Studio 就會幫你建立一個 ProjectInstaller.cs 類別 ( 繼承自 Installer 類別 ),並自動新增兩個與 Windows 服務安裝有關的控制項,分別是 serviceProcessInstaller1 與 serviceInstaller1,方便你直接 Windows 服務安裝時應該設定的參數。

接著,Visual Studio 就會幫你建立一個 ProjectInstaller.cs 類別 ( 繼承自 Installer 類別 ),並自動新增兩個與 Windows 服務安裝有關的控制項,方便你直接設定。

然後,你就修改將這兩個控制項的相關參數,設定 serviceInstaller1 的顯示名稱(DisplayName)、描述(Description)、服務名稱(ServiceName)、啟動類型(StartType),以及設定 serviceProcessInstaller1 的啟動帳戶(Account),設定完這些就差不多大功告成了。

設定 serviceInstaller1 的顯示名稱(DisplayName)、描述(Description)、服務名稱(ServiceName)、啟動類型(StartType) 設定 serviceProcessInstaller1 的啟動帳戶(Account)

最後,將專案編譯之後,該專案所編譯出來的組件(Assembly)就具有「安裝能力」,只要透過 .NET 2.0 提供的安裝程式工具 (Installutil.exe)就可以將該服務順利安裝至系統內。

假設編譯出來的組件名稱是 WindowsService1.exe,那麼執行 Windows 服務安裝的指令就是:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe  WindowsService1.exe

解除安裝的指令是:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe /u WindowsService1.exe

大功告成!

---

如果你的 Windows 服務會接受外部的連線,且需要在安裝過程中直接將目前組件加入到 Windows 防火牆的「允許的應用程式」清單中的話,就可以運用以下技巧進行設定。

首先必須先加入 Windows 防火牆的 COM 元件參考,並選取 COM 頁籤中的 NetFwTypeLib 元件 ( C:\WINDOWS\system32\hnetcfg.dll ):

Add Reference

Add Reference - 選取 COM 頁籤中的 NetFwTypeLib 元件 ( C:\WINDOWS\system32\hnetcfg.dll )

接著進入你的 ProjectInstaller.cs 的類別中加入以下方法,加入前請記得先在檔案最上方先引用 NetFwTypeLib 命名空間 ( using NetFwTypeLib; ):

/// <summary>
/// 將目前組件的程式加入到 Windows 防火牆的「允許的應用程式」清單中
/// </summary>
private void SetupWindowsFirewall()
{
    try
    {
        Type NetFwMgrType = Type.GetTypeFromProgID("HNetCfg.FwMgr", false);
        INetFwMgr mgr = (INetFwMgr)Activator.CreateInstance(NetFwMgrType);

        Type NetFwAuthorizedApplicationType = Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication", false);
        INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)Activator.CreateInstance(NetFwAuthorizedApplicationType);

        app.Name = serviceInstaller1.ServiceName;
        app.Enabled = true;
        app.ProcessImageFileName = System.Reflection.Assembly.GetExecutingAssembly().Location;
        app.Scope = NET_FW_SCOPE_.NET_FW_SCOPE_ALL;

        mgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(app);
    }
    catch (Exception ex)
    {
        System.Diagnostics.EventLog.WriteEntry("Service1Installer", ex.ToString());
    }
}

最後,再到 ProjectInstaller() 建構函數裡加上一段 SetupWindowsFirewall(); 即可完成設定,之後只要透過安裝程式工具 (Installutil.exe)就不止可以將該服務順利安裝至系統,還可以在安裝過程中順便將安裝的組件加入到 Windows 防火牆的「允許的應用程式」清單中。

由於上述的 SetupWindowsFirewall 方法牽扯到 Windows Firewall 提供的 HNetCfg.FwMgr COM 元件,我不多做說明,不過這段程式幾乎直接抓過去就能用了,有興趣研究如何操作 Windows Firewall 的人請自行參考本文章最後的相關連結

相關連結