![Windows 服务:我可以配置当前工作目录吗?](https://linux22.com/image/506278/Windows%20%E6%9C%8D%E5%8A%A1%EF%BC%9A%E6%88%91%E5%8F%AF%E4%BB%A5%E9%85%8D%E7%BD%AE%E5%BD%93%E5%89%8D%E5%B7%A5%E4%BD%9C%E7%9B%AE%E5%BD%95%E5%90%97%EF%BC%9F.png)
默认情况下,Windows 服务在 sytem32 目录中启动(通常C:\WINDOWS\system32
)。
有没有办法设置不同的工作目录?我正在考虑下面的一些注册表参数HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService
。
那么,这能做到吗?
答案1
SetCurrentDirectory
您可以使用 DLL 注入在进程启动后进行调用。这需要您构建一个注入器应用程序以及要注入的 DLL。有一些教程;我发现的最好的两个可能是:
您需要大量的 C++ 编程背景(以及可运行的构建环境)才能完成此任务。
但是,这假设服务正在查看当前目录。另一种可能性是它正在使用%path%
。您说它“从开始system32
,尝试更多位置,最终尝试自己的目录”,所以这对我来说更有可能。
将您在 中看到的目录procmon
与您的进行比较%path%
。如果它们相同,请考虑修改运行该服务的用户的SYSTEM %path%
或%path%
,以便您希望它搜索的目录位于第一位。
不过,我相信 Fred 是对的——你不太可能通过做这些事情看到任何显著的性能提升,除非它真的发生了。非常经常。简单的文件打开操作并不是特别昂贵,特别是如果它是本地路径并且文件实际上不存在。
答案2
在服务主函数中执行以下操作:
- 调用
GetModuleFilename
。它将以 的形式检索模块(exe)文件名(包括路径)C:\path\to\exe\your_service.exe
。 - 使用字符串操作(可能使用
std::string
函数find_last_of()
)来查找最后一个反斜杠。从那里剥离/修剪字符串以获取模块的路径,从而获取 exe 的目录。 - 调用该函数
SetCurrentDirectory
,瞧!
答案3
和 MattB 一样,我不知道有什么方法可以在不访问源代码的情况下更改服务的工作目录。对于这种特定情况,相对于全文索引操作所需的 I/O 量,额外的目录检查可能不会带来那么多不必要的磁盘活动。即使您可以优化它们,全文索引本质上也会占用大量磁盘空间。
答案4
向参数键添加“AppDirectory”字符串值,并将该值设置为所需的工作目录。