NSSM(Non-Sucking Service Manager)是一支免費開源工具,可以把幾乎任何 EXE 包裝成 Windows 服務,讓它開機自動啟動、當掉自動重啟、並把 stdout/stderr 導向日誌檔。
版本現況:NSSM 最後一個正式釋出版是 2014 年的 2.24;預覽版 2.25 在官方 git 上持續有提交,但無正式發布日期。功能已相當完整,只是不要期待活躍的版本更新。
NSSM 與 SC 命令的差異
Windows 內建的 sc.exe 可以註冊服務,但它的前提是「被包裝的程式本身已實作 Windows Service API」——也就是說要會回應 SCM 的 Start/Stop/Pause 訊號。一般的 console EXE 沒有這套邏輯,用 sc 直接包會秒停。
NSSM 的做法是自己當服務宿主,在 SCM 和你的 EXE 中間做代理:SCM 叫 NSSM 停,NSSM 再去 terminate 你的 EXE。因此任何 console 程式都能包,不需要改原始碼。
其他 SC 辦不到、NSSM 能辦到的:
- stdout / stderr 轉存為日誌檔,不用另外掛 wrapper script
- 崩潰後自動重啟,可設延遲時間與最大重試次數
- 設定服務專屬的環境變數(
AppEnvironmentExtra) - 依賴其他服務(服務啟動順序)
- 提供 GUI 介面,不用背
sc參數語法
什麼時候用 SC 就夠:程式本身已實作 Service API,或只是要設定服務的啟動類型、描述等屬性,sc config 語法就很夠用。
下載與安裝
- 前往 nssm.cc/download,下載最新壓縮包
- 解壓縮,依系統選
win32/nssm.exe或win64/nssm.exe - 把
nssm.exe放到固定路徑,例如C:\Tools\NSSM\nssm.exe - 把該目錄加進系統的 PATH 環境變數,之後就能直接輸入
nssm而不用打完整路徑
所有 NSSM 指令都需要以系統管理員身份執行命令提示字元或 PowerShell。
建立服務
圖形介面方式
1 | nssm install <服務名稱> |
會開啟 GUI,填入三個必要欄位:
- Path:EXE 的完整路徑,例如
C:\MyApp\MyProgram.exe - Startup directory:EXE 所在目錄(程式找相對路徑的設定檔時會用到)
- Arguments:命令列參數(選填)
填完按「Install service」。
命令列方式
1 | nssm install <服務名稱> <EXE完整路徑> [參數] |
範例:
1 | nssm install MyService "C:\MyApp\MyProgram.exe" -config "C:\MyApp\config.ini" |
路徑含空格記得加引號。
進階設定
建立服務後,用 nssm set 調整各項設定。
顯示名稱與描述
1 | nssm set MyService DisplayName "My App Service" |
這兩個值會出現在「服務」管理員(services.msc)的清單裡。
啟動類型
1 | nssm set MyService Start SERVICE_AUTO_START |
可選值:SERVICE_AUTO_START(自動)、SERVICE_DELAYED_AUTO_START(延遲自動)、SERVICE_DEMAND_START(手動)、SERVICE_DISABLED。
環境變數
1 | nssm set MyService AppEnvironmentExtra "MYVAR=hello" "PATH=C:\MyApp;%PATH%" |
務必用 AppEnvironmentExtra,不要用 AppEnvironment。 AppEnvironment 會完整取代服務的環境區塊,且不展開 %PATH%(NSSM 不做變數展開,%PATH% 會被當成字面值),結果是原本的系統 PATH 全部消失,程式可能找不到相依的 DLL 或工具。AppEnvironmentExtra 是在現有環境基礎上附加,%PATH% 能正常展開。
崩潰重啟
1 | nssm set MyService AppExit Default Restart |
Default 指任何退出碼都觸發重啟。也可以針對特定退出碼設定不同行為:
1 | nssm set MyService AppExit 0 Exit |
這樣程式正常結束(exit code 0)就不重啟,異常退出才重啟。
日誌輸出
1 | nssm set MyService AppStdout "C:\Logs\MyService.log" |
目錄必須存在,NSSM 不會自動建立。
管理服務
1 | nssm start MyService |
移除服務
移除前先確認服務已停止,否則 SCM 可能需要重開機才能清除:
1 | nssm stop MyService |
常見問題
服務啟動後立即停止
最快的排查順序:
- 直接在命令列手動執行 EXE(用相同的使用者帳號、相同的工作目錄),確認程式本身能正常跑
- 執行
nssm status MyService,看目前狀態 - 開啟「事件檢視器」→「Windows 記錄」→「應用程式」,篩選來源為 NSSM 或你的程式名稱,錯誤訊息通常在這裡
- 確認
AppStdout/AppStderr日誌有沒有寫入內容
「確保所有必要的依賴項都可用」這種說法太籠統——實際上最常見的是工作目錄設錯導致程式找不到相對路徑的設定檔,或服務帳號缺少存取某個資料夾的權限。
無法連線到服務
服務預設以 LocalSystem 帳號執行,這個帳號的網路存取行為與一般使用者不同(例如存取網路共用資料夾、AD 資源)。改用有適當網路權限的 AD 帳號或 NetworkService 往往能解決。
互動式程式的限制
NSSM 雖然支援將需要 stdin/stdout 的程式包成服務,但 Windows Vista 之後的 Session 0 隔離讓服務無法與登入使用者的桌面互動:服務產生的視窗或對話框不會顯示給使用者,鍵盤滑鼠事件也進不去。程式「看起來沒動靜」但實際上可能卡在等待輸入。
如果你的 EXE 需要互動,包成服務之前要先改成從設定檔讀參數,或透過 IPC(named pipe、TCP socket)接受指令,不能靠終端機互動。
最佳實踐
- 指定專屬的服務帳號,而不是跑在
LocalSystem下,避免權限過大 - 設定
AppStdout和AppStderr,問題出現時才有日誌可查 - 在測試機驗證完整的 install → start → stop → remove 流程,再上生產機
- 服務名稱用英數字加底線或連字號,避免空格;
DisplayName才是給人看的




