在Win7下使用服务调用应用程序的问题 由于项目需要,需要在Win7下编写一个服务,这个服务的作用就是定时检测指定程序是否运行,如果没有运行则使用WinExec将此程序运行起来。现在服务和程序已经写成,并且在XP下运行正常。但是在Win7下运行的时候,每次服务调用Exe的时候总是会提示“交互式服务检测”。请问在Win7下如果使用服务调用Exe运行呢?? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 win7中服务和桌面程序运行于不同的session,他们是互相隔离的。由服务程序创建的进程不具备桌面交互功能。给你一个办法。枚举系统中的explorer.exe进程,判断这个explorer进程是跟当前活动桌面是同一个session,然后取得这个进程的token,然后有createprocessAsUser来以这个token来创建你的进程。 能具体点吗?我在网上找的资料说windows7的服务程序会受到会话的隔离,服务程序运行在session0,用户能看到的在session1,2,...你可以使用NtOpenProcessToken打开自己的进程令牌,再使用NtDuplicateToken复制令牌,并用NtSetInformationToken更改新令牌的会话id为active console sessionid,由WTSGetActiveConsoleSessionId获得,最后使用CreateProcessInternalW创建进程,注意传入新令牌句柄,还要在STARTUPINFO中设置lpdesktop为WinSta0\Default下边是我写的代码BOOL bSuccess = FALSE;STARTUPINFO si = {0};// 进程信息PROCESS_INFORMATION pi = {0};si.cb = sizeof(si);si.lpDesktop = "WinSta0\Default";HANDLE hTokenThis = NULL;HANDLE hDuplicatedToken = NULL;LPVOID lpEnvironment = NULL;DWORD dwSessionID;HANDLE hThisProcess = GetCurrentProcess();WriteDebug("GetCurrentProcess - %d",hThisProcess);OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);// 复制令牌if (DuplicateTokenEx(hTokenThis,MAXIMUM_ALLOWED, NULL,SecurityIdentification,TokenPrimary,&hDuplicatedToken) == FALSE){DWORD dwError = GetLastError();WriteDebug("DuplicateTokenEx - %d",dwError);//goto Cleanup;}//更改新令牌的会话id为active console sessionidSetTokenInformation(hDuplicatedToken, TokenSessionId, &dwSessionID, sizeof(DWORD));// 获得当前Session IDdwSessionID = WTSGetActiveConsoleSessionId();WriteDebug("WTSGetActiveConsoleSessionId - %d",dwSessionID);// 获得当前Session的用户令牌if (WTSQueryUserToken(dwSessionID, &hTokenThis) == FALSE){DWORD dwError = GetLastError();WriteDebug("WTSQueryUserToken - %d",dwError);//goto Cleanup;}// 创建用户Session环境if (CreateEnvironmentBlock(&lpEnvironment,hDuplicatedToken, FALSE) == FALSE){DWORD dwError = GetLastError();WriteDebug("CreateEnvironmentBlock - %d",dwError);//goto Cleanup;}// 在复制的用户Session下执行应用程序,创建进程。// 通过这个进程,就可以显示各种复杂的用户界面了if (CreateProcessAsUser(hDuplicatedToken,m_strThePath, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE |CREATE_UNICODE_ENVIRONMENT,lpEnvironment, NULL, &si, &pi) == FALSE){DWORD dwError = GetLastError();WriteDebug("CreateProcessAsUser - %d",dwError);//goto Cleanup;}CloseHandle(pi.hProcess);CloseHandle(pi.hThread);bSuccess = TRUE;// 清理工作Cleanup:if (!bSuccess){WriteDebug("无法创建复杂UI");}if (hTokenThis != NULL)CloseHandle(hTokenThis);if (hDuplicatedToken != NULL)CloseHandle(hDuplicatedToken);if (lpEnvironment != NULL)DestroyEnvironmentBlock(lpEnvironment); 我是这样写的,但是调试时,是有问题的。 这代码啥意思? 请教Delphi中如何将OLE对象的word内容(包括图片等)插入已打开的word文档中? SakEmail发邮件 请教在DELPHI中如何识别图象是蓝色或黄色呢? 欢迎大家提意见,开发一个打印组件 如何能控制edit.txt里的内容,例如我只允许用户输入整型数字 200分求一个很简单的用到ADO的三层结构的例子 文件加密,突发奇想 关于用TADOQuery删除记录的几个小问题。 再谈关于c/s模式数据库的问题?? delphi ODAC 如何正确保存UFT8的字符串
给你一个办法。
枚举系统中的explorer.exe进程,判断这个explorer进程是跟当前活动桌面是同一个session,然后取得这个进程的token,然后有createprocessAsUser来以这个token来创建你的进程。
我在网上找的资料说windows7的服务程序会受到会话的隔离,服务程序运行在session0,用户能看到的在session1,2,...
你可以使用NtOpenProcessToken打开自己的进程令牌,再使用NtDuplicateToken复制令牌,并用NtSetInformationToken更改新令牌的会话id为active console sessionid,由WTSGetActiveConsoleSessionId获得,最后使用CreateProcessInternalW创建进程,注意传入新令牌句柄,还要在STARTUPINFO中设置lpdesktop为WinSta0\Default下边是我写的代码
BOOL bSuccess = FALSE;
STARTUPINFO si = {0};
// 进程信息
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
si.lpDesktop = "WinSta0\Default";
HANDLE hTokenThis = NULL;
HANDLE hDuplicatedToken = NULL;
LPVOID lpEnvironment = NULL;
DWORD dwSessionID;
HANDLE hThisProcess = GetCurrentProcess();
WriteDebug("GetCurrentProcess - %d",hThisProcess);
OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
// 复制令牌
if (DuplicateTokenEx(hTokenThis,MAXIMUM_ALLOWED, NULL,SecurityIdentification,
TokenPrimary,&hDuplicatedToken) == FALSE)
{
DWORD dwError = GetLastError();
WriteDebug("DuplicateTokenEx - %d",dwError);
//goto Cleanup;
}
//更改新令牌的会话id为active console sessionid
SetTokenInformation(hDuplicatedToken, TokenSessionId, &dwSessionID, sizeof(DWORD));
// 获得当前Session ID
dwSessionID = WTSGetActiveConsoleSessionId();
WriteDebug("WTSGetActiveConsoleSessionId - %d",dwSessionID);
// 获得当前Session的用户令牌
if (WTSQueryUserToken(dwSessionID, &hTokenThis) == FALSE)
{
DWORD dwError = GetLastError();
WriteDebug("WTSQueryUserToken - %d",dwError);
//goto Cleanup;
}
// 创建用户Session环境
if (CreateEnvironmentBlock(&lpEnvironment,
hDuplicatedToken, FALSE) == FALSE)
{
DWORD dwError = GetLastError();
WriteDebug("CreateEnvironmentBlock - %d",dwError);
//goto Cleanup;
}
// 在复制的用户Session下执行应用程序,创建进程。
// 通过这个进程,就可以显示各种复杂的用户界面了
if (CreateProcessAsUser(hDuplicatedToken,m_strThePath, NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE |CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, NULL, &si, &pi) == FALSE)
{
DWORD dwError = GetLastError();
WriteDebug("CreateProcessAsUser - %d",dwError);
//goto Cleanup;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
bSuccess = TRUE;
// 清理工作
Cleanup:
if (!bSuccess)
{
WriteDebug("无法创建复杂UI");
}
if (hTokenThis != NULL)
CloseHandle(hTokenThis);
if (hDuplicatedToken != NULL)
CloseHandle(hDuplicatedToken);
if (lpEnvironment != NULL)
DestroyEnvironmentBlock(lpEnvironment);
我是这样写的,但是调试时,是有问题的。