如何使用Python和instsrv.exe/srvany.exe创建Windows服务

该博客将探讨如何使用Python脚本结合instsrv.exe和srvany.exe工具将任何程序转换为Windows服务。这不仅有助于程序以SYSTEM账户运行,还能实现随机器启动而自启动,并且可以隐藏不必要的窗口。以下是详细的步骤和代码示例。

概述

在Windows系统中,服务是一种特殊类型的程序,它在后台运行,通常没有用户界面。通过将程序转换为服务,我们可以确保程序在系统启动时自动运行,并且可以在后台持续运行,不受用户登录状态的影响。

准备工作

在开始之前,你需要确保你的系统中安装了以下工具:

  1. instsrv.exesrvany.exe:这两个工具是Microsoft Windows Resource Kits的一部分,用于安装和卸载服务。
  2. Python:我们将使用Python编写脚本,因此需要确保Python环境已安装。

安装和配置服务

首先,我们需要将instsrv.exesrvany.exe复制到C:\Windows\System32\目录下(对于64位系统,还需要复制到C:\Windows\SysWow64\目录)。接下来,我们将编写一个Python脚本来检查特定服务是否正在运行,并在未运行时启动该服务。

Python脚本详解

以下是Python脚本的详细解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import sys
import os
import psutil
import wmi
import winreg

def start():
"""
检查特定服务是否正在运行,如果没有,它会通过执行一些命令来启动该服务并退出程序。
"""
try:
if getattr(sys, "frozen", False):
pro_path = os.path.normpath(os.path.join(
sys.executable,
os.pardir, # 上一级目录(..)
))
else:
pro_path = os.path.normpath(os.path.join(
os.path.abspath(__file__),
os.pardir, # 上一级目录(..)
os.pardir
))
processes = []
for proc in psutil.process_iter():
processes.append(proc)

# 检查系统上是否正在运行名为“ssguard”的服务。
# 如果未找到该服务,它将继续使用“instsrv.exe”和“srvany.exe”实用程序安装和配置该服务。
# 然后,它为该服务创建一个注册表项并设置一些参数,例如应用程序路径和目录。最后,它使用“sc start”命令启动服务
# 并退出程序。
wmiobj = wmi.WMI()
services = wmiobj.Win32_Service()
server_name = "ssguard"
if server_name not in [i.Name for i in services]:
instsrv_path = os.path.join(pro_path, "utils", "instsrv.exe")
srvany_path = os.path.join(pro_path, "utils", "srvany.exe")
if ' ' in instsrv_path and ' ' in srvany_path:
os.system(f'"{instsrv_path}" {server_name} "{srvany_path}"')
elif ' ' in instsrv_path:
os.system(f'"{instsrv_path}" {server_name} {srvany_path}')
elif ' ' in srvany_path:
os.system(f'{instsrv_path} {server_name} "{srvany_path}"')
else:
os.system(f'{instsrv_path} {server_name} {srvany_path}')
print("执行命令:", f'{instsrv_path} {server_name} {srvany_path}')
root_key = winreg.OpenKey(
winreg.HKEY_LOCAL_MACHINE, r"SYSTEM\CurrentControlSet\Services")
server = winreg.CreateKey(root_key, server_name)
parameters = winreg.CreateKey(server, "Parameters")
winreg.SetValueEx(parameters, "Application", 0, winreg.REG_SZ,
os.path.join(pro_path, "deploymenttools.exe"))
winreg.SetValueEx(parameters, "AppDirectory",
0, winreg.REG_SZ, pro_path)
os.system("sc start ssguard")
sys.exit()
except:
print(traceback.format_exc())
sys.exit()

代码解释

  1. 路径获取:首先,我们获取当前Python脚本的路径,这将用于定位instsrv.exesrvany.exe工具。
  2. 服务检查:使用wmi模块检查名为ssguard的服务是否正在运行。
  3. 服务安装:如果服务未运行,使用instsrv.exe安装服务,并指定srvany.exe作为服务外壳。
  4. 注册表配置:在注册表中设置服务的参数,包括应用程序路径和目录。
  5. 服务启动:使用sc start命令启动服务。

结论

通过上述步骤和代码,可以轻松地将任何程序转换为Windows服务,实现自动启动和后台运行。这种方法不仅提高了程序的稳定性和可用性,还有助于隐藏不必要的用户界面,使系统更加整洁。