該庫可用於安裝/開始/停止/卸載節點腳本作為生產環境的Windows背景服務。這不是開發應用程序的工具,它是用於釋放它們的工具。該工具會生成可執行的可執行文件,該可執行文件將在計算機上安裝的任何版本的Node.js運行您的應用程序。
如果您需要支持這些操作系統,請參見Node-MAC和Node-Linux。
如果您需要我,請發推文(@goldglovecb)。
![]() | ![]() | ![]() | ![]() |
不能贊助? 考慮提名@coreybutler為GitHub明星。 | |||
節點窗口中有以下功能:
exec命令。安裝節點窗口的推薦方法是使用NPM,使用全局標誌:
npm install -g node-windows
然後,在您的項目root中,運行:
npm link node-windows
然而;可以使用沒有全局標誌的節點 - 窗口(即直接安裝到項目根部)。有關為什麼這不是推薦方法的更多詳細信息,則可以在整個讀書中獲得。
在Windows上使用本機節點模塊可能會很爛。大多數天然模塊不是以二進制格式分佈的。取而代之的是,這些模塊依靠npm利用節點GYP來構建項目。這意味著開發人員需要在系統上安裝Visual Studio(以及潛在的其他軟件),以安裝本機模塊。這是可移植的,但很痛苦……主要是因為Visual Studio本身超過2GB。
節點窗口不使用本機模塊。有一些二進制/EXE實用程序,但是運行更複雜的任務所需的一切都以易於使用的格式打包和分發。因此,不需要視覺工作室...至少不是這個模塊。
節點窗口具有一個實用程序,可以將node.js腳本作為Windows服務運行。請注意,像所有Windows服務一樣,創建一個需要管理特權。要使用節點窗口創建服務,請準備一個類似的腳本:
var Service = require ( 'node-windows' ) . Service ;
// Create a new service object
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
nodeOptions : [
'--harmony' ,
'--max_old_space_size=4096'
]
//, workingDirectory: '...'
//, allowServiceLogon: true
} ) ;
// Listen for the "install" event, which indicates the
// process is available as a service.
svc . on ( 'install' , function ( ) {
svc . start ( ) ;
} ) ;
svc . install ( ) ;上面的代碼創建了一個新的Service對象,提供了一個漂亮的名稱和描述。 script屬性標識了應作為服務運行的node.js腳本。運行此操作後,從Windows Services實用程序中可以看到該腳本。
Service對象發出以下事件:
在上面的示例中,腳本聆聽install事件的腳本。由於完成服務安裝後,該事件是觸發的,因此可以安全地啟動服務。
節點窗口創建的服務類似於Windows上運行的大多數其他服務。它們可以通過Windows Service實用程序,通過NET START或NET STOP命令啟動/停止,甚至使用SC實用程序進行管理。
可能需要指定命令行切換到您的腳本。您可以通過在服務配置中設置scriptOptions來做到這一點:
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
scriptOptions : '-c C:\path\to\somewhere\special -i'
} ) ;有時,您可能需要提供服務,並在創建服務時傳遞的靜態數據。您可以通過在服務配置中設置環境變量來執行此操作,如下所示:
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
env : {
name : "HOME" ,
value : process . env [ "USERPROFILE" ] // service is now able to access the user who created its' home directory
}
} ) ;您還可以提供一個數組來設置多個環境變量:
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
env : [ {
name : "HOME" ,
value : process . env [ "USERPROFILE" ] // service is now able to access the user who created its' home directory
} ,
{
name : "TEMP" ,
value : path . join ( process . env [ "USERPROFILE" ] , "/temp" ) // use a temp directory in user's home directory
} ]
} ) ;有時您可能需要指定一個特定的node可執行文件以運行腳本。您可以通過在服務配置中設置execPath來做到這一點,如下所示:
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
execPath : 'C:\path\to\specific\node.exe'
} ) ;如果您需要指定特定的用戶或特定憑據來管理服務,則以下屬性可能會有所幫助。
user屬性是帶有三個鍵的對象: domain , account和password 。這可以用來識別服務庫應使用的用戶執行系統命令。默認情況下,域設置為本地計算機名稱,但是可以使用Active Directory或LDAP域覆蓋它。例如:
app.js
var Service = require ( 'node-windows' ) . Service ;
// Create a new service object
var svc = new Service ( {
name : 'Hello World' ,
script : require ( 'path' ) . join ( __dirname , 'helloworld.js' ) ,
//, allowServiceLogon: true
} ) ;
svc . logOnAs . domain = 'mydomain.local' ;
svc . logOnAs . account = 'username' ;
svc . logOnAs . password = 'password' ;
...如果您希望服務模塊作為特定用戶運行命令,則必須明確定義帳戶和密碼。默認情況下,它將使用啟動該過程的用戶帳戶(即啟動node app.js )運行。
如果要指示WinSW允許服務帳戶登錄,請指定allowServiceLogon: true 。默認情況下,由於某些用戶在沒有服務登錄的情況下經歷了此問題,因此默認情況下是禁用的。
另一個屬性是sudo 。此屬性具有一個稱為password的單個屬性。通過提供此信息,服務模塊將嘗試使用啟動該帳戶的過程和密碼的用戶帳戶運行命令。這僅應用於具有管理特權的帳戶。
app.js
var Service = require ( 'node-windows' ) . Service ;
// Create a new service object
var svc = new Service ( {
name : 'Hello World' ,
script : require ( 'path' ) . join ( __dirname , 'helloworld.js' )
} ) ;
svc . sudo . password = 'password' ;
...該服務也可以取決於其他Windows服務。
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
dependsOn : [ "serviceA" ]
} ) ;卸載先前創建的服務在句法上與安裝相似。
var Service = require ( 'node-windows' ) . Service ;
// Create a new service object
var svc = new Service ( {
name : 'Hello World' ,
script : require ( 'path' ) . join ( __dirname , 'helloworld.js' )
} ) ;
// Listen for the "uninstall" event so we know when it's done.
svc . on ( 'uninstall' , function ( ) {
console . log ( 'Uninstall complete.' ) ;
console . log ( 'The service exists: ' , svc . exists ) ;
} ) ;
// Uninstall the service.
svc . uninstall ( ) ;卸載過程僅刪除特定於過程的文件。它不會刪除您的node.js腳本!
很多東西!
長期運行過程和監視:
Windows服務的內置服務恢復相當有限,並且不能輕易從代碼配置。因此,節點 - 窗口會在node.js腳本周圍創建一個包裝器。該包裝器負責以智能和可配置的方式重新啟動失敗的服務。例如,如果您的腳本由於未知錯誤而崩潰,則節點窗口將嘗試重新啟動它。默認情況下,每秒都會發生這種情況。然而;如果腳本具有致命的缺陷,使其反复崩潰,則將不必要的開銷添加到系統中。節點 - 窗口通過增加重新啟動之間的時間間隔並限制最大重新啟動數來處理這一點。
更聰明的重新啟動不會撞擊您的服務器:
使用默認設置,Node-Windows每次重新啟動腳本都需要在等待間隔中增加25%。在默認設置(1秒)的情況下,第一秒鐘後進行了第一個重新啟動嘗試。第二次發生在1.25秒後。 1.56秒後的第三次(1.25增加了25%),依此類推。最初的等待時間和增長率都是配置選項,可以傳遞給新Service 。例如:
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
script : 'C:\path\to\helloworld.js' ,
wait : 2 ,
grow : .5
} ) ;在此示例中,等待期將從2秒開始,並增加50%。因此,第二次嘗試將在3秒鐘後,而第四秒將是4.5秒。
不要自己!
重複的回收可能會因不良腳本而永遠持續下去。為了應對這些情況,節點窗口支持兩種帽子。使用maxRetries將限制最大重新啟動嘗試。默認情況下,這是無限的。將其設置為3將告訴該過程在失敗3次後不再重新啟動該過程。另一個選擇是maxRestarts ,它可以在60秒內限制嘗試重新啟動的數量。例如,如果將其設置為3(默認值),並且該過程反复崩潰/重新啟動,則節點窗口將在60秒的窗口中停止在第三個週期後停止嘗試。這兩個配置選項都可以設置,就像wait或grow一樣。
最後,如果您希望腳本在錯誤退出時根本不重新啟動,則可以將稱為abortOnError的屬性設置為true 。
Node-Windows使用Winsw實用程序為每個Node.js腳本創建一個部署為服務的唯一.exe 。由myappname.exe和myappname.xml創建和填充一個稱為daemon的目錄。 XML文件是可執行文件的配置。此外, winsw將在此目錄中為自身創建一些日誌(在事件日誌中可以查看)。
myappname.exe文件啟動了節點 - 窗口包裝器,該包裝器負責監視和管理腳本。由於此文件是節點窗口的一部分,因此移動節點 - 窗口目錄可能會導致.exe文件無法找到node.js腳本。然而;根據建議的安裝說明,如果節點 - 窗口在全球安裝,這不應該是問題。
所有這些特定於守護程序的文件都是在稱為daemon的子目錄中創建的,該台將其創建在保存node.js腳本的同一目錄中。卸載服務將刪除這些文件。
事件記錄
用節點窗口創建的服務有兩個事件日誌,可以通過Windows事件查看器查看。名為myappname.exe的日誌源為可執行文件提供了基本日誌記錄。它可用於查看整個服務何時開始/停止或有錯誤。 Node-Windows Monitor使用了第二個以您的服務名稱(即我的應用程序名稱)命名的日誌。可以使用Node-Windows Event Loggging從Node.js腳本寫入該日誌。
截至v0.1.0的新事件是基於非C ++的事件記錄實用程序。該實用程序可以寫入事件日誌,使您的日誌從事件查看器中可見。它在引擎蓋下使用EventCreate。
創建一個記錄器:
var EventLogger = require ( 'node-windows' ) . EventLogger ;
var log = new EventLogger ( 'Hello World' ) ;
log . info ( 'Basic information.' ) ;
log . warn ( 'Watch out!' ) ;
log . error ( 'Something went wrong.' ) ;看起來與:
也可以通過Node-Windows Event Logging獲得一些較少使用的選項。
log . auditSuccess ( 'AUser Login Success' ) ;
log . auditFailure ( 'AUser Login Failure' ) ;每個日誌類型(信息,警告,錯誤,審核和審計)方法(可選)都接受兩個其他參數,包括代碼和回調。默認情況下,事件代碼為1000 ,如果沒有另行指定。為了提供帶有日誌消息的自定義事件代碼並將該消息寫入控制台,可以使用以下代碼:
注意: EventCreate似乎僅支持自定義ID <= 1000。
log . info ( 'Something different happened!' , 700 , function ( ) {
console . log ( 'Something different happened!' ) ;
} ) ;默認情況下,事件日誌都是APPLICATION範圍的一部分。然而;也可以使用SYSTEM日誌。為此,必須將配置對像傳遞給新日誌:
var EventLogger = require ( 'node-windows' ) . EventLogger ;
var log = new EventLogger ( {
source : 'My Event Log' ,
eventLog : 'SYSTEM'
} ) ;包裝器生成的警告事件日誌可以通過在創建服務時禁用它來抑制它。默認情況下啟用了警告日誌。
var svc = new Service ( {
name : 'Hello World' ,
description : 'The nodejs.org example web server.' ,
disableWarningLogs : true ,
} ) ;節點 - 窗口帶有多個命令,以簡化MS Windows上的任務。
高架與Linux/Mac上的sudo相似。它試圖將當前用戶的特權提升到本地管理員。使用此功能不需要密碼,但確實要求當前用戶具有管理特權。沒有這些特權,該命令將失敗,而access denied錯誤。
在啟用UAC的系統上,這可能會提示用戶允許繼續進行:
文法:
elevate(cmd[,options,callback])
require('child_process').exec(cmd,<OPTIONS>,callback) 。require('child_process').exec(cmd,options,<CALLBACK>) 。 Sudo的作用與Linux/Mac上的sudo相似。與Elevate不同,它需要密碼,但不會提示用戶許可繼續進行。像Elevate一樣,這仍然需要用戶的管理特權,否則命令將失敗。此和抬高()之間的主要區別是提示。
文法:
sudo(cmd,password[,options,callback])
require('child_process').exec(cmd,<OPTIONS>,callback) 。require('child_process').exec(cmd,options,<CALLBACK>) 。 此異步命令確定當前用戶是否具有管理特權。它將布爾值傳遞給回調,如果用戶是管理員或false ,則返回true 。
例子
var wincmd = require ( 'node-windows' ) ;
wincmd . isAdminUser ( function ( isAdmin ) {
if ( isAdmin ) {
console . log ( 'The user has administrative privileges.' ) ;
} else {
console . log ( 'NOT AN ADMIN' ) ;
}
} ) ; 列表方法查詢操作系統以獲取運行過程列表。
var wincmd = require ( 'node-windows' ) ;
wincmd . list ( function ( svc ) {
console . log ( svc ) ;
} , true ) ;這返回運行過程。在上面的示例中提供可選的true參數提供了一個帶有詳細輸出的列表。輸出特定於操作系統的版本。這是Windows 8計算機上詳細輸出的示例。
[ {
ImageName : 'cmd.exe' ,
PID : '12440' ,
SessionName : 'Console' ,
'Session#' : '1' ,
MemUsage : '1,736 K' ,
Status : 'Unknown' ,
UserName : 'Machine\Corey' ,
CPUTime : '0:00:00' ,
WindowTitle : 'N/A'
} , {
ImageName : 'tasklist.exe' ,
PID : '1652' ,
SessionName : 'Console' ,
'Session#' : '1' ,
MemUsage : '8,456 K' ,
Status : 'Unknown' ,
UserName : 'Machine\Corey' ,
CPUTime : '0:00:00' ,
WindowTitle : 'N/A'
} ]常規(非verbose)輸出通常提供ImageName , PID , SessionName , Session# , MemUsage和CPUTime 。
此方法將通過PID殺死一個過程。
var wincmd = require ( 'node-windows' ) ;
wincmd . kill ( 12345 , function ( ) {
console . log ( 'Process Killed' ) ;
} ) ;在此示例中,過程ID 12345將被殺死。重要的是要注意,執行此節點腳本的用戶帳戶可能需要管理特權。
如果您在示例中遇到問題,請查看TESTS.md文件。
如果您遇到了無效的安裝事件,請查看在安裝過程中創建的daemon程序目錄,以確保在那裡.exe和.xml文件。在某些情況下,主要是在_un_installation期間,該過程暫時鎖定日誌文件是可能的,從而防止窗口刪除它。在這種情況下,只需再次運行卸載即可。在大多數情況下,這將解決該問題。如果不是,請在再次運行安裝之前手動卸下daemon程序目錄。
有許多貢獻者已經做了從攻讀功能到幫助我陷入困境的懈怠的所有工作。我的幫助非常感謝。
特別感謝@arthurblake的修改終於添加了。多虧了 @Hockeytim11,他幫助編譯和更新了許多出色的問題,並開始為其他節點 - *庫提供支持。
Winsw和Sudowin是各自所有者的版權。 WINSW是根據MIT許可證分發的。 Sudowin是根據BSD許可證分發的。
所有其他腳本均為版權(C)Corey Butler在MIT許可下。
(麻省理工學院許可證)
版權(C)2013 Corey Butler
特此免費授予任何獲得此軟件副本和相關文檔文件副本(“軟件”)的人,以無限制處理該軟件,包括不限於使用,複製,修改,合併,合併,發布,分發,分發,分發,撒下,sublicense和/或允許軟件的副本,並允許對以下條件提供以下條件,以下是以下條件。
上述版權通知和此許可通知應包含在軟件的所有副本或大量部分中。
該軟件是“按原樣”提供的,沒有任何形式的明示或暗示保證,包括但不限於適銷性,適合特定目的和非侵害的保證。在任何情況下,作者或版權持有人都不應對任何索賠,損害賠償或其他責任責任,無論是在合同,侵權的訴訟中還是其他責任,是由軟件,使用或與軟件中的使用或其他交易有關的。