设置程序开机启动的办法有多种,坑不少,坑在结尾。
1、计划任务设置开机启动
如果是图形界面的程序,需要先设置开机自动登录,然后再通过计划任务设置图形界面的程序开机自启,比如通过计划任务设置开机自启渲染软件(渲染软件不支持远程调用)。如果没有设置开机自动登录,图形界面的程序没法自动运行。
开机自动登录是通过注册表配置的,以管理员身份powershell执行以下代码即可,黑体部分是密码
net user Administrator "HaUX$j=;Rd-xDw}"
echo "REGEDIT4" > c:temp.reg
echo "[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWinlogon]" >> c:temp.reg
echo "`"AutoAdminLogon`"=`"1`"">> c:temp.reg
echo "`"DefaultUserName`"=`"Administrator`"" >> c:temp.reg
echo "`"DefaultPassword`"=`"HaUX$j=;Rd-xDw}`"" >> c:temp.reg
cmd /c "reg import c:temp.reg"
2、shell:startup
运行shell:startup会打开这个目录:
%USERPROFILE%AppDataRoamingMicrosoftWindowsStart MenuProgramsStartup
记事本新建 start.vbs (后缀是.vbs,不是.txt),写入如下代码:
CreateObject("WScript.Shell").Run "cmd /c C:startup.bat",0
注意:将代码中的路径修改为你实际的路径。
将 start.vbs 文件剪切到 %USERPROFILE%AppDataRoamingMicrosoftWindowsStart MenuProgramsStartup 文件夹下,注意加入安全软件的信任,否则会被拦截。
3、通过srvany/srvany-ng/SrvanyUI、nssm添加开机自启服务
srvany来自微软Resource Kit Tools(rktools.exe),原本链接如下,但微软已经下掉了,普通浏览器访问是404,但是因为迅雷里有缓存,通过迅雷下载能下载到
http://download.microsoft.com/download/8/e/c/8ec3a7d8-05b4-440a-a71e-ca3ee25fe057/rktools.exe
用7z解压工具,提取rktools.exe会得到rktools.msi,继续提取rktools.msi会得到很多.exe文件,这里用到instsrv.exe和srvany.exe。
注意,不要把这2个文件放到system32目录,64位系统里会报错,类似的软件还有tcproute等。
srvany-ng兼容srvany,用法参考
https://github.com/birkett/srvany-ng
https://docs.microsoft.com/en-US/troubleshoot/windows-client/deployment/create-user-defined-service
在目前所有的windows系统都可以使用srvany*,但需要注意下,64位系统不能将srvany*置于system32目录
这里其实不用instsrv.exe是完全可以的,因为instsrv.exe命令可以用sc.exe命令替代,只是语法上不同而已。
由于rktools.exe发过几个版本,里面的instsrv.exe和srvany.exe我在网上找到一个靠谱的版本(比上面迅雷下载的rktools.exe提取出来的更好),特地放到这里
①sc.exe调用srvany.exe添加其他可执行文件为服务,用sc.exe管理服务
用sc.exe创建ip_relay 服务
sc.exe create ip_relay binpath= "C:addservicesrvany.exe" start= auto displayname= "ip_relay"
配置ip_relay 服务的ParametersAppEnvironment注册表参数,这里要特别注意,这个参数不是必须的,加上了反而出问题,我测试8KB的srvany.exe用AppEnvironment可能会有问题,13KB的没事,由于不统一,这里我用@rem仅作注释而已,并不会真的执行
@rem reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v "AppEnvironment" /t reg_multi_sz /d "temp=C:Windowstemp; PATH=C:ip_relay_1.1binwin32;C:Windows;C:WindowsSystem32; " /f
以下3句是配置ip_relay 服务的ParametersAppDirectory、ParametersApplication、ParametersAppParameters,其中Application和AppParameters是必须的
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v AppDirectory /t REG_SZ /d "C:ip_relay_1.1binwin32" /f
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v Application /t REG_SZ /d "C:ip_relay_1.1binwin32ip_relay.exe" /f
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v AppParameters /t REG_SZ /d "9090 localhost 80" /f
以下2句看需要而定,1个是描述服务的,1个是设置依赖的,如果没有依赖,可以执行sc.exe config ip_relay depend= ""
sc.exe description ip_relay "ip_relay,一个端口转发程序,用法示例:ip_relay.exe 9090 localhost 80"
sc.exe config ip_relay depend= tcpip/dhcp/dnscache/Winmgmt
启动或停止服务用sc.exe或net都行
sc.exe start ip_relay
netstat -ano|findstr :9090
sc.exe stop ip_relay
netstat -ano|findstr :9090
这里稍微介绍下ip_relay.exe的功能,它是转发端口的,比如你服务器有个80端口的web服务,通过http://localhost:80/ 能访问,
执行ip_relay.exe 9090 localhost 80 后,你执行netstat -ano|findstr :9090发现9090端口已经监听了,此时你通过http://localhost:80/ 和http://localhost:9090/都能访问。
net start ip_relay
netstat -ano|findstr :9090
net stop ip_relay
netstat -ano|findstr :9090
删除服务
sc.exe delete ip_relay
②SrvanyUI点鼠标添加服务、管理服务,比上面的命令行更简单
③用nssm.exe添加服务、管理服务
nssm官网:http://www.nssm.cc/download
nssm install ip_relay "C:ip_relay_1.1binwin32ip_relay.exe"
@rem sc.exe create ip_relay binpath= "C:WindowsSystem32nssm.exe" start= auto displayname= "ip_relay"
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v Application /t REG_SZ /d "C:ip_relay_1.1binwin32ip_relay.exe" /f
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v AppParameters /t REG_SZ /d "9090 localhost 80" /f
sc.exe description ip_relay "ip_relay,一个端口转发程序,用法示例:ip_relay.exe 9090 localhost 80"
sc.exe config ip_relay depend= tcpip/dhcp/dnscache/Winmgmt
nssm start ip_relay
netstat -ano|findstr :9090
nssm stop ip_relay
nssm edit ip_relay
nssm remove ip_relay
nssm.exe跟srvany.exe/srvany-ng的注册表大同小异,详见https://github.com/birkett/srvany-ng
其中这3个注册表键值,srvany*和nssm具有通用性,不同的是srvany的AppEnvironment在nssm里变成AppEnvironmentExtra
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v AppDirectory /t REG_SZ /d "C:ip_relay_1.1binwin32" /f
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v Application /t REG_SZ /d "C:ip_relay_1.1binwin32ip_relay.exe" /f
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v AppParameters /t REG_SZ /d "9090 localhost 80" /f
srvany:
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v "AppEnvironment" /t reg_multi_sz /d "temp=C:Windowstemp; PATH=C:ip_relay_1.1binwin32;C:Windows;C:WindowsSystem32; " /f
nssm:
reg add "HKLMSYSTEMCurrentControlSetServicesip_relayParameters" /v "AppEnvironmentExtra" /t reg_multi_sz /d "temp=C:Windowstemp; PATH=C:ip_relay_1.1binwin32;C:Windows;C:WindowsSystem32; " /f
总之,3种方案都不错
最后,说说过程中的坑
①srvany.exe我找到2个版本,一个8KB、一个13KB,8KB的srvany.exe,我用ip_relay做实验时,加了AppEnvironment注册表后端口不能监听,不加AppEnvironment则正常。而用13KB的,加或不加AppEnvironment都正常。
②能不配AppEnvironment就不要配,这个不是必须的,很少用到,坑不少,比如①提到的,13KB的srvany加这个注册表的话是AppEnvironment,而nssm加的话,就要调整为AppEnvironmentExtra。
③srvany*(含srvany-ng)不能放在system32目录,否则会报错;nssm则没事,32位、64位的nssm.exe放在system32目录都OK。
④由于添加服务是敏感操作,第三方安全软件可能会拦截,比如下面这个,显示系统正在关机,实际并没有,这是360拦截,在执行配置服务的命令前,需要先关闭所有会话里的安全软件,比如你开了2个会话,2个会话里都有360,你在A会话里把360关了,但B会话里的360还在运行,此时你在A会话执行配置服务的命令或其他360认为的不安全行为,仍然会被拦截。
⑤涉及的注册表键值,作为字符串,不要带双引号,在nssm场景中,带了双引号的话,启动服务时可能报错
⑥卸载服务前,把每个登录会话(比如vnc、远程多会话可能开了多个登录会话)里services.msc服务列表打开的小窗口、注册表窗口都关闭彻底了、把每个登录会话里的安全软件都退出了再卸载服务,否则可能导致删除不干净。
⑦关于桌面交互,2008R2/Win7以上的高版本系统已经弃用,你开启了也看不到效果,比如把notepad 设置为服务、勾选桌面交互是看不到效果,没看到有notepad 的窗口出现,只在后台看到服务启动后有个notepad .exe的进程出现,服务关闭的时候进程又消失,图形界面效果在2008R2/Win7能看到。
⑧设置为服务的程序,前提是有一个可置于后台的功能,如果没有置于后台的功能,那直接设置为服务后启动会报1531。
比如我附件里给的那个WindowsFormsApplication_Exe.exe,你双击打开它有图形界面,
同时,人家软件作为服务置于后台时有个功能"每5秒钟打印一次时间戳"。
这个Demo的作者特别棒,特意在title上写清了"我是WinForm,也是Windows服务"
WindowsFormsApplication_Exe.exe作为服务,会在WindowsFormsApplication_Exe.exe同目录下产生一个.txt文件,每5秒打印一下时间戳。
WindowsFormsApplication_Exe.exe的代码参考:
https://www.cnblogs.com/micro-chen/p/5885899.html
https://www.cnblogs.com/ldjbase/p/5405262.html
链接里第三个方案的下载压缩包里的srvany.exe才是ok的,这个13KB,比8KB的那个更好一些。
我找了个【是WinForm,但不是Windows服务】的Notepad 来练手,果然踩坑了,踩坑是因为没有借助srvany*或nssm,直接用sc.exe配的,当然借助srvany*或nssm配的notepad 还是能看到图形界面的。
如果直接用sc.exe create配置服务,如果程序没有置于后台的功能,那直接设置为服务后启动会报1531
比如公共镜像里的"QCloud服务"是已经弃用的网络初始化服务,这里正好拿来练手,在早年的腾讯云Windows系统里,如果"QCloud服务"有异常,我都是通过下面命令修复的,因为这个程序就是专门开发的置于后台的服务,而不是WinForm。
这里因为最新镜像已经弃用"QCloud服务",我只是展示下命令
创建服务
sc.exe create QCloudService binpath= ""C:Program FilesQCloudQCloudServiceQCloudService.exe" -k" start= auto displayname= "QCloud服务"
添加描述
sc.exe description QCloudService "Windows Server初始化辅助服务,自动配置QCloud网络IP地址"
配置依赖视情况而定,由于是网络初始化服务,我添加了4个跟网络相关的服务作为它的依赖项;其实新的初始化服务cloudbase-init也可以这样添加依赖sc.exe config cloudbase-init depend= tcpip/dhcp/dnscache/Winmgmt
sc.exe config QCloudService depend= tcpip/dhcp/dnscache/Winmgmt
这里是练手,仅仅添加而已,不要尝试启动服务,可能带来异常,加上服务后,马上删除服务
sc.exe delete QCloudService
如果照猫画虎,把"QCloud服务"替换成了别的程序比如notepad ,启动服务的时候会发现报错了,为啥?因为notepad 就没有后台功能
sc.exe create notepad binpath= "C:Program FilesNotepad notepad .exe" start= auto displayname= "notepad "
sc.exe description notepad "notepad ,比notepad更好用!"
sc.exe config notepad depend= ""
sc.exe start notepad
没啥卵用,执行sc.exe delete notepad 删除。