node-windows

Tweet me (@goldglovecb) if you need me.


node-windows

用法介绍:nodejs 将node命令启动为windows服务运行(node-windows使用)

This library can be used to install/start/stop/uninstall Node scripts as Windows background services for production environments. 此库可用于将节点脚本安装/启动/停止/卸载为生产环境的Windows后台服务。This is not a tool for developing applications, it is a tool for releasing them.这不是开发应用程序的工具,而是发布应用程序的一个工具。

See node-mac and node-linux if you need to support those operating systems.如果需要支持这些操作系统,请参阅node-macnode-linux

Overview概述

The following features are available in node-windows:节点窗口中提供了以下功能:

Installation安装

The recommended way to install node-windows is with npm, using the global flag:安装节点windows的推荐方法是使用npm,使用全局标志:

npm install -g node-windows

Then, in your project root, run:然后,在项目根目录中运行:

npm link node-windows

However; it is possible to use node-windows without the global flag (i.e. install directly into the project root). 然而可以使用没有全局标志的节点窗口(即直接安装到项目根目录)。More details regarding why this is not the recommended approach are available throughout this Readme.有关为什么这不是推荐方法的更多详细信息,请参阅本自述。

NO NATIVE MODULES不用原生模块

Using native node modules on Windows can suck. 在Windows上使用本机节点模块可能会很糟糕。Most native modules are not distributed in a binary format. 大多数本机模块不是以二进制格式分发的。Instead, these modules rely on npm to build the project, utilizing node-gyp. 相反,这些模块依赖于npm来构建项目,利用node-gypThis means developers need to have Visual Studio (and potentially other software) installed on the system, just to install a native module. 这意味着开发人员需要在系统上安装Visual Studio(可能还有其他软件),以便安装本机模块。This is portable, but painful... mostly because Visual Studio itself is over 2GB.这是可移植的,但很痛苦…主要是因为Visual Studio本身超过2GB。

node-windows does not use native modules.Node-windows不使用原生模块。 There are some binary/exe utilities, but everything needed to run more complex tasks is packaged and distributed in a readily usable format. 有一些二进制/exe实用程序,但运行更复杂任务所需的一切都以易于使用的格式打包和分发。So, no need for Visual Studio... at least not for this module.所以,不需要Visual Studio…至少不需要这个模块。


Windows Services服务

node-windows has a utility to run Node.js scripts as Windows services. node windows有一个实用程序,可以将Node.js脚本作为windows服务运行。Please note that like all Windows services, creating one requires administrative privileges. 请注意,与所有Windows服务一样,创建服务需要管理权限。To create a service with node-windows, prepare a script like:要使用节点窗口创建服务,请准备以下脚本:

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();

The code above creates a new Service object, providing a pretty name and description. 上面的代码创建了一个新的Service对象,提供了一个漂亮的名称和描述。The script attribute identifies the Node.js script that should run as a service. script属性标识应作为服务运行的Node.js脚本。Upon running this, the script will be visible from the Windows Services utility.运行此脚本后,将从Windows服务实用程序中看到该脚本。

Windows Service

The Service object emits the following events:Service对象发出以下事件:

In the example above, the script listens for the install event. 在上面的示例中,脚本侦听install事件。Since this event is fired when a service installation is complete, it is safe to start the service.由于此事件在服务安装完成时触发,因此启动服务是安全的。

Services created by node-windows are similar to most other services running on Windows. 节点窗口创建的服务类似于windows上运行的大多数其他服务。They can be started/stopped from the windows service utility, via NET START or NET STOP commands, or even managed using the sc utility.它们可以通过windows服务实用程序、NET STARTNET STOP命令启动/停止,甚至可以使用sc实用程序进行管理。

Command-line Options命令行选项

It may be desired to specify command-line switches to your script. 可能需要为脚本指定命令行开关。You can do this by setting the scriptOptions within the service config:您可以通过在服务配置中设置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'
});

Environment Variables环境变量

Sometimes you may want to provide a service with static data, passed in on creation of the service. 有时,您可能希望为服务提供静态数据,这些数据在创建服务时传递。You can do this by setting environment variables in the service config, as shown below:您可以通过在服务配置中设置环境变量来实现这一点,如下所示:

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
  }
});

You can also supply an array to set multiple environment variables:您还可以提供一个数组来设置多个环境变量:

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 Executable Path节点可执行路径

There are times when you may want to specify a specific node executable to use to run your script. 有时,您可能需要指定用于运行脚本的特定node可执行文件。You can do this by setting the execPath in the service config, as shown below:您可以通过在服务配置中设置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 Account Attributes用户帐户属性

If you need to specify a specific user or particular credentials to manage a service, the following attributes may be helpful.如果需要指定特定用户或特定凭据来管理服务,则以下属性可能很有用。

The user attribute is an object with three keys: domain,account, and password. user属性是一个具有三个键的对象:domainaccountpasswordThis can be used to identify which user the service library should use to perform system commands.这可用于标识服务库应使用哪个用户执行系统命令。By default, the domain is set to the local computer name, but it can be overridden with an Active Directory or LDAP domain. 默认情况下,域设置为本地计算机名,但可以使用活动目录或LDAP域覆盖。For example:例如:

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';
...

Both the account and password must be explicitly defined if you want the service module to run commands as a specific user. 如果希望服务模块作为特定用户运行命令,则必须明确定义帐户和密码。By default, it will run using the user account that launched the process (i.e. who launched node app.js).默认情况下,它将使用启动进程的用户帐户(即,启动了node app.js的用户)运行。

If you want to instruct winsw to allow service account logins, specify allowServiceLogon: true. 如果要指示winsw允许服务帐户登录,请指定allowServiceLogon:trueThis is disabled by default since some users have experienced issues running this without service logons.这在默认情况下是禁用的,因为一些用户在没有服务登录的情况下运行时遇到问题。

The other attribute is sudo. 另一个属性是sudoThis attribute has a single property called password. 此属性有一个名为password的属性。By supplying this, the service module will attempt to run commands using the user account that launched the process and the password for that account. 通过提供此信息,服务模块将尝试使用启动进程的用户帐户和该帐户的密码运行命令。This should only be used for accounts with administrative privileges.这只能用于具有管理权限的帐户。

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';
...

Cleaning Up: Uninstall a Service清理:卸载服务

Uninstalling a previously created service is syntactically similar to installation.卸载以前创建的服务在语法上类似于安装。

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();

The uninstall process only removes process-specific files. 卸载过程仅删除特定于进程的文件。It does NOT delete your Node.js script!它不会删除您的Node.js脚本!

What Makes node-windows Services Unique?是什么使节点windows服务独一无二?

Lots of things!很多东西!

Long Running Processes & Monitoring:长期运行流程和监控:

The built-in service recovery for Windows services is fairly limited and cannot easily be configured from code. Windows服务的内置服务恢复相当有限,无法通过代码轻松配置。Therefore, node-windows creates a wrapper around the Node.js script. 因此,node windows围绕Node.js脚本创建了一个包装器。This wrapper is responsible for restarting a failed service in an intelligent and configurable manner. 该包装器负责以智能和可配置的方式重新启动故障服务。For example, if your script crashes due to an unknown error, node-windows will attempt to restart it. 例如,如果您的脚本由于未知错误而崩溃,节点窗口将尝试重新启动它。By default, this occurs every second. 默认情况下,这每秒钟发生一次。However; if the script has a fatal flaw that makes it crash repeatedly, it adds unnecessary overhead to the system. 然而如果脚本存在致命缺陷,导致其反复崩溃,则会给系统增加不必要的开销。node-windows handles this by increasing the time interval between restarts and capping the maximum number of restarts.节点窗口通过增加重新启动之间的时间间隔和限制最大重新启动次数来处理此问题。

Smarter Restarts That Won't Pummel Your Server:更智能的重启不会影响您的服务器:

Using the default settings, node-windows adds 25% to the wait interval each time it needs to restart the script. 使用默认设置,节点windows在每次需要重新启动脚本时会将等待间隔增加25%。With the default setting (1 second), the first restart attempt occurs after one second. 使用默认设置(1秒),第一次重新启动尝试在1秒后发生。The second occurs after 1.25 seconds. 第二次发生在1.25秒之后。The third after 1.56 seconds (1.25 increased by 25%) and so on. 第三次是在1.56秒后(1.25增加25%),以此类推。Both the initial wait time and the growth rate are configuration options that can be passed to a new Service. 初始等待时间和增长率都是可以传递给新Service的配置选项。For example:例如:

var svc = new Service({
  name:'Hello World',
  description: 'The nodejs.org example web server.',
  script: 'C:\\path\\to\\helloworld.js',
  wait: 2,
  grow: .5
});

In this example, the wait period will start at 2 seconds and increase by 50%. 在本例中,等待时间将从2秒开始,并增加50%。So, the second attempt would be 3 seconds later while the fourth would be 4.5 seconds later.因此,第二次尝试将在3秒之后,而第四次尝试将是4.5秒之后。

Don't DOS Yourself!不要自己动手!

Repetitive recycling could potentially go on forever with a bad script. 重复的回收可能会永远伴随着一个糟糕的脚本。To handle these situations, node-windows supports two kinds of caps. 为了处理这些情况,节点窗口支持两种CAP。Using maxRetries will cap the maximum number of restart attempts. 使用maxRetries将限制重新启动尝试的最大次数。By default, this is unlimited. 默认情况下,这是无限的。Setting it to 3 would tell the process to no longer restart a process after it has failed 3 times. 将其设置为3将告诉进程在失败3次后不再重新启动进程。Another option is maxRestarts, which caps the number of restarts attempted within 60 seconds. 另一个选项是maxRestarts,它限制60秒内尝试的重启次数。For example, if this is set to 3 (the default) and the process crashes/restarts repeatedly, node-windows will cease restart attempts after the 3rd cycle in a 60 second window. 例如,如果将其设置为3(默认值),并且进程重复崩溃/重启,则节点窗口将在60秒窗口中的第三个周期后停止重启尝试。Both of these configuration options can be set, just like wait or grow.这两个配置选项都可以设置,就像waitgrow一样。

Finally, an attribute called abortOnError can be set to true if you want your script to not restart at all when it exits with an error.最后,如果您希望脚本在出现错误退出时根本不重新启动,则可以将名为abortOnError的属性设置为true

How Services Are Made如何提供服务

node-windows uses the winsw utility to create a unique .exe for each Node.js script deployed as a service. node-windows使用winsw实用程序为作为服务部署的每个Node.js脚本创建唯一的.exeA directory called daemon is created and populated with myappname.exe and myappname.xml. 创建一个名为daemon的目录,并用myappnam.exemyappname.xml填充。The XML file is a configuration for the executable. XML文件是可执行文件的配置。Additionally, winsw will create some logs for itself in this directory (which are viewable in the Event log).此外,winsw将在此目录中为自己创建一些日志(可在事件日志中查看)。

The myappname.exe file launches the node-windows wrapper, which is responsible for monitoring and managing the script. myappname.exe文件启动节点windows包装器,该包装器负责监视和管理脚本。Since this file is a part of node-windows, moving the node-windows directory could result in the .exe file not being able to find the Node.js script. 由于该文件是节点窗口的一部分,移动节点窗口目录可能导致.exe文件无法找到Node.js脚本。However; this should not be a problem if node-windows is installed globally, per the recommended installation instructions.然而如果按照建议的安装说明在全局安装节点windows,则这应该不是问题。

All of these daemon-specific files are created in a subdirectory called daemon, which is created in the same directory where the Node.js script is saved. 所有这些特定于守护程序的文件都创建在一个名为daemon的子目录中,该子目录与保存Node.js脚本的目录相同。Uninstalling a service will remove these files.卸载服务将删除这些文件。

Event Logging事件日志记录

Services created with node-windows have two event logs that can be viewed through the Windows Event Viewer. 使用节点窗口创建的服务有两个事件日志,可以通过windows事件查看器查看。A log source named myappname.exe provides basic logging for the executable file. 名为myappname.exe的日志源为可执行文件提供基本日志记录。It can be used to see when the entire service starts/stops or has errors. 它可用于查看整个服务何时启动/停止或出现错误。A second log, named after your service name (i.e. My App Name), is used by the node-windows monitor. 节点windows监视器使用以您的服务名称(即我的应用程序名称)命名的第二个日志。It is possible to write to this log from the Node.js script using the node-windows Event Logging.可以使用节点windows事件日志从Node.js脚本写入此日志。


Event Logging事件日志记录

New as of v0.1.0 is a non-C++ based event logging utility. v0.1.0的新版本是一个基于非C++的事件日志工具。This utility can write to the event log, making your logs visible from the Event Viewer.此实用程序可以写入事件日志,使您的日志在事件查看器中可见。

To create a logger:要创建记录器:

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.');

Looks similar to:

Event Logging in node-windows

Some lesser-used options are also available through node-windows event logging.一些较少使用的选项也可通过节点窗口事件日志记录使用。

log.auditSuccess('AUser Login Success');
log.auditFailure('AUser Login Failure');

Each log type (info, warn, error, auditSuccess, and auditFailure) method optionally accepts two additional arguments, including a code and callback. 每个日志类型(info、warn、error、auditSuccess和auditFailure)方法可选地接受两个附加参数,包括codecallbackBy default, the event code is 1000 if not otherwise specified. 默认情况下,如果未另行指定,事件代码为1000To provide a custom event code with a log message and write that message to the console, the following code could be used:要提供带有日志消息的自定义事件代码并将该消息写入控制台,可以使用以下代码:

log.info('Something different happened!', 1002, function(){
  console.log('Something different happened!');
});

By default, event logs are all part of the APPLICATION scope. 默认情况下,事件日志都是APPLICATION范围的一部分。However; it is also possible to use the SYSTEM log.然而也可以使用SYSTEM日志。To do this, a configuration object must be passed to the new log:为此,必须将配置对象传递到新日志:

var EventLogger = require('node-windows').EventLogger;
var log = new EventLogger({
  source: 'My Event Log',
  eventLog: 'SYSTEM'
});

Commands命令

node-windows ships with several commands to simplify tasks on MS Windows.node windows附带了几个命令来简化MS windows上的任务。

elevate

Elevate is similar to sudo on Linux/Mac. Elevate类似于Linux/Mac上的sudoIt attempts to elevate the privileges of the current user to a local administrator. 它尝试将当前用户的权限提升为本地管理员。Using this does not require a password, but it does require that the current user have administrative privileges. 使用它不需要密码,但需要当前用户具有管理权限。Without these privileges, the command will fail with a access denied error.如果没有这些权限,命令将失败,并出现access denied错误。

On systems with UAC enabled, this may prompt the user for permission to proceed:在启用UAC的系统上,这可能会提示用户允许继续:

UAC Prompt

Syntax:

elevate(cmd[,options,callback])

sudo

Sudo acts similarly to sudo on Linux/Mac. Sudo的作用类似于Linux/Mac上的sudoUnlike elevate, it requires a password, but it will not prompt the user for permission to proceed. elevate不同,它需要密码,但不会提示用户是否允许继续。Like elevate, this still requires administrative privileges for the user, otherwise the command will fail.elevate一样,这仍然需要用户的管理权限,否则命令将失败。The primary difference between this and elevate() is the prompt.这与elevate()之间的主要区别在于提示。

Syntax:

sudo(cmd,password[,options,callback])

isAdminUser

This asynchronous command determines whether the current user has administrative privileges. 此异步命令确定当前用户是否具有管理权限。It passes a boolean value to the callback, returning true if the user is an administrator or false if it is not.它向回调传递一个布尔值,如果用户是管理员,则返回true,否则返回false

Example实例

var wincmd = require('node-windows');

wincmd.isAdminUser(function(isAdmin){
  if (isAdmin) {
    console.log('The user has administrative privileges.');
  } else {
    console.log('NOT AN ADMIN');
  }
});

list

The list method queries the operating system for a list of running processes.list方法向操作系统查询正在运行的进程的列表。

var wincmd = require('node-windows');

wincmd.list(function(svc){
  console.log(svc);
},true);

This returns an array of running processes. 这将返回正在运行的进程的数组。Supplying the optional true argument in the above example provides a list with verbose output. 在上面的示例中提供可选的true参数提供了一个具有详细输出的列表。The output is specific to the version of the operating system. Here is an example of verbose output on a Windows 8 computer.输出特定于操作系统的版本。下面是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'
}]

The regualar (non-verbose) output typically provides the ImageName,PID,SessionName, Session#, MemUsage, and CPUTime.regualar(非详细)输出通常提供ImageNamePIDSessionNameSession#MemUsageCPUTime

kill

This method will kill a process by PID.此方法将通过PID终止进程。

var wincmd = require('node-windows');

wincmd.kill(12345,function(){
  console.log('Process Killed');
});

In this example, process ID 12345 would be killed. It is important to note that the user account executing this node script may require administrative privileges.在此示例中,进程ID 12345将被终止。需要注意的是,执行此节点脚本的用户帐户可能需要管理权限。

Troubleshooting故障排除

If you're experiencing issues with the examples, please review the TESTS.md file.如果您在示例中遇到问题,请查看TESTS.md文件。

If you are encountering the invalidinstallation event, take a look at the daemon directory that is created during the installation to make sure the .exe and .xml files are there. 如果遇到invalidinstallation事件,请查看在安装过程中创建的daemon目录,以确保存为.exe.xml文件。In some circumstances, primarily during _un_installation, it is possbile for the process to temporarily lock a log file, which prevents Windows from removing it. 在某些情况下,主要是在_un_installation期间,进程可以临时锁定日志文件,这会阻止Windows删除它。In this scenario, simply run the uninstall again. 在这种情况下,只需再次运行卸载。In most cases this will fix the issue. 在大多数情况下,这将解决问题。If not, manually remove the daemon directory before running the installation again.如果不是,请在再次运行安装之前手动删除daemon目录。

Thank You鸣谢

There have been many contributors who have done everything from committing features to helping pick up slack while I've been swamped. 有很多贡献者在我忙得不可开交的时候做了很多事情,从提交特性到帮助我解决问题。I'm incredibly appreciative for the help.我非常感谢你的帮助。

Special thanks to @arthurblake whose modifications have FINALLY been added. 特别感谢@arthurblake,最终添加了修改。Thanks to @hockeytim11, who helped compile and update a bunch of outstanding issues and started bringing support to the other node-* libraries.感谢@hockeytim11,他帮助编译和更新了一系列悬而未决的问题,并开始为其他node-*库提供支持。

Licenses许可

winsw and sudowin are the copyrights of their respective owners. winsw和sudowin是各自所有者的版权。winsw is distributed under an MIT license. winsw是根据MIT许可证发行的。sudowin is distributed under a BSD license.sudowin是根据BSD许可证发行的。

All other scripts are Copyright (c) Corey Butler under an MIT license.所有其他脚本均由麻省理工学院许可的Corey Butler版权所有。

(The MIT License)

Copyright (c) 2013 Corey Butler

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:特此免费授予获得本软件和相关文档文件(“软件”)副本的任何人在不受限制的情况下处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许向其提供本软件的人这样做,符合以下条件:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.上述版权声明和本许可声明应包含在软件的所有副本或实质部分中。

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 本软件按“原样”提供,无任何明示或暗示的担保,包括但不限于适销性、特定用途适用性和非侵权担保。IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.在任何情况下,作者或版权持有人均不对任何索赔、损害赔偿或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中,由软件或软件的使用或其他交易引起或与之相关。