怎么在windows 服务程序里面调用一个控制台的程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么在windows 服务程序里面调用一个控制台的程序相关的知识,希望对你有一定的参考价值。

1、服务是与其他用户程序隔离的,通常运行于会话0。
2、服务的工作目录为系统目录(System32、SysWOW64),通过服务启动的应用程序也是如此。
3、最简单的实现是:在操作系统中创建计划任务(使用任务计划程序)
4、如果你确实希望通过服务程序来实现,且更新程序不需要用户交互,那么可以只需要在“Update”的主函数(Main)第一行加一句“System.IO.Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);”;
5、如果你确实希望通过服务程序来实现,且更新程序需要用户交互,那么需要使用到Win32API中的“CreateProcessAsUser”函数,相应地还需要用到“WTSEnumerateSessions”和“WTSQueryUserToken”。
参考如下网页:
https://www.cnblogs.com/datacool/p/CreateProcessAsUser_Win_api.html
https://www.cnblogs.com/gnielee/archive/2010/04/07/session0-isolation-part1.html
https://www.cnblogs.com/gnielee/archive/2010/04/08/session0-isolation-part2.html
https://docs.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessasusera

https://docs.microsoft.com/zh-cn/previous-versions/aa379608(v=vs.85)
参考技术A 自动更新程序已经写好(Update.exe),当程序运行的时候自动更新,现在手动更新(双击Update.exe)可以实现更新,但是上级要求必须在凌晨1点钟的时候启用一次更新,所以写了一个WindowsService服务,在监听函数里面写入:if (DateTime.Now.Hour.ToString() =="0") FunctionLibrary = new AssistantFunctionLibrary(); FunctionLibrary.RegisterActionInf("采集更新开始!"); Process.Start(System.Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\Update.exe");

如何使用 C++ 从 Windows 服务运行 .exe 文件

【中文标题】如何使用 C++ 从 Windows 服务运行 .exe 文件【英文标题】:How can I run a .exe file from a windows service using c++ 【发布时间】:2021-02-25 06:48:12 【问题描述】:

我是 Windows 服务和 Visual Studio 的新手。我正在尝试从 wind32 应用程序启动 .exe 文件。代码工作正常,没有错误。我正在使用 CreateProcess() 方法并检查该方法是否正常运行。里面没有问题。我调用的 .exe 文件只是创建文本文档。当我从控制台调用该 .exe 文件时,它工作正常,它会创建文件。但是当我从 wind32 应用程序调用它时,它不会创建任何文件。我正在使用 Visual Studio 2019。这是我调用 .exe 文件的代码。 `

STARTUPINFO info;
PROCESS_INFORMATION processInfo;
ZeroMemory(&info, sizeof(info));
info.cb = sizeof(info);
ZeroMemory(&processInfo, sizeof(processInfo));

LPCWSTR path = L"C:\\HP\\...(pathofexe).exe";
bool bSuccess = CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);

if (bSuccess)

    cout << "Success";

else

    cout << "Error : " << GetLastError() << endl;
`

【问题讨论】:

猜测运行该服务的用户没有访问所有必需文件的权限 该文件可能不在您期望的位置,因为新进程的工作目录将是调用它的应用程序的目录。附带说明一下,您必须自己关闭返回到LPPROCESS_INFORMATION 的两个句柄,使用CloseHandle 能否详细说明 @Rapunzel 那是给谁的? (使用标签) @IWonderWhatThisAPIDoes For you 【参考方案1】:

关于 cmets 中讨论的工作目录不匹配,该文件可能不存在,因为它只是在其他地方。

你打电话:

CreateProcess(path, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);

假设您已阅读documentation,您知道第 8 个参数指定了新进程将运行的目录。因为你使用NULL,所以这个目录会和调用者进程的目录一样,我假设"C:\\Users\\HP\\source\\repos\\ThisThingsName\\Debug\\"

这本身不是问题,但考虑到上下文,我相信 被调用者 (SampleService.exe) 从其相对路径 "\\Success.txt" 而不是完整路径调用文件函数是对吗?

在这种情况下,当您手动打开SampleService.exe 时,Success.txt 将出现在"C:\\Users\\HP\\source\\repos\\SampleService\\Debug\\" 中。但是,当您使用CreateProcess 打开它时,它会在"C:\\Users\\HP\\source\\repos\\ThisThingsName\\Debug\\" 中运行(因为您没有另外指定),这也是Success.txt 出现的位置。

实际上,当我键入此内容时,我开始怀疑它。您没有检查它在资源管理器中的显示位置吗?

【讨论】:

关于调用者进程,是的,它与被调用者在同一目录下(即“C:\\Users\\HP\\source\\repos\\Tests\\x64\ \Debug\\Tests.exe)。Success.txt 只是一个检查 CreateProcess() 是否正常工作的文件。(因为它是 wind32 应用程序,我创建它是为了检查它)。问题是当我运行相同的代码时作为控制台应用,它运行正常。但作为windows服务应用,它没有调用Tests.exe @Rapunzel 没有打电话? CreateProcess 是否返回 false,或者...? 它返回 true 并创建 Success.txt。但是,没有调用 Test.exe。正如我之前提到的,Tests.exe 创建一个文本文件(带有正在运行的 Windows 服务的列表)。但是没有创建应该由 Tests.exe 创建的文件。 @Rapunzel 哦...这与我预期的结构完全不同...所以有两个文件有问题。您是否可以访问 Tests 的代码,或者有办法知道里面发生了什么? 实际上,我正在尝试从 SampleService(wind32 应用程序)运行 Tests.exe 文件。但是, CreateProcess() 方法运行得很好,但 Tests.exe 不是。从 Windows 服务调用 .exe 文件有什么不同的方法。

以上是关于怎么在windows 服务程序里面调用一个控制台的程序的主要内容,如果未能解决你的问题,请参考以下文章

在mfc下怎么调用一个win32控制台?并且自动向该控制台输入一段信息?

iis。关于js调用并打开服务器上的word文档

windows任务计划程序是怎么回事,有啥用途,该怎么设置??

c++主函数如何调用"WinMain"函数

windows xp 设置server 怎样开机自动启动

web服务器是怎么建立起来的 web服务器建立方法简述