问题在于,Window服务在会话#0中运行,但已登录的用户会话为1,2等。
因此,问题是:如何以这样的方式从窗口服务启动进程,以便它在当前登录用户的会话中运行?
我要强调的是,问题不是如何在特定帐户下启动进程(这是显而易见的- Process.Start(new ProcessStartInfo("..") { UserName=..,Password=..})). 即使我安装我的Windows以在当前用户帐户下运行,服务也将在会话#0中运行。设置“允许服务与桌面交互”也无济于事。
我的Windows服务基于.NET。
更新: 首先,.NET在这里没有任何作用,它实际上是纯Win32事物。 以下代码位于我的Windows服务中(使用win32函数通过P / InKove进行C#处理,我跳过了导入签名,它们都在这里 - http://www.pinvoke.net/default.aspx/advapi32/CreateProcessWithLogonW.html):
var startupInfo = new StartupInfo()
{
lpDesktop = "WinSta0\\Default",
cb = Marshal.SizeOf(typeof(StartupInfo)),
};
var processInfo = new ProcessInformation();
string command = @"c:\windows\Notepad.exe";
string user = "Administrator";
string password = "password";
string currentDirectory = System.IO.Directory.GetCurrentDirectory();
try
{
bool bRes = CreateProcessWithLogonW(user, null, password, 0,
command, command, 0,
Convert.ToUInt32(0),
currentDirectory, ref startupInfo, out processInfo);
if (!bRes)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
catch (Exception ex)
{
writeToEventLog(ex);
return;
}
WaitForSingleObject(processInfo.hProcess, Convert.ToUInt32(0xFFFFFFF));
UInt32 exitCode = Convert.ToUInt32(123456);
GetExitCodeProcess(processInfo.hProcess, ref exitCode);
writeToEventLog("Notepad has been started by WatchdogService. Exitcode: " + exitCode);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
代码到达了"WatchdogService已启动Notepad。Exitcode:" + exitCode所在的行。Exitcode为3221225794。但是没有任何新的记事本被启动。我错在哪里?
WTSEnumerateSessions
api没有关于排序的任何保证,但是该代码将选择列表中最后一个活动会话。我不认为您有任何办法知道哪个会话是“正确”的,但如果有的话,您可以修改那个for
循环。我假设这是在服务器操作系统上? - murrayju