由于项目需要,需要在Win7下编写一个服务,这个服务的作用就是定时检测指定程序是否运行,如果没有运行则使用WinExec将此程序运行起来。现在服务和程序已经写成,并且在XP下运行正常。但是在Win7下运行的时候,每次服务调用Exe的时候总是会提示“交互式服务检测”。请问在Win7下如果使用服务调用Exe运行呢??

解决方案 »

  1.   

    win7中服务和桌面程序运行于不同的session,他们是互相隔离的。由服务程序创建的进程不具备桌面交互功能。
    给你一个办法。
    枚举系统中的explorer.exe进程,判断这个explorer进程是跟当前活动桌面是同一个session,然后取得这个进程的token,然后有createprocessAsUser来以这个token来创建你的进程。
      

  2.   

    能具体点吗?
    我在网上找的资料说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);
     我是这样写的,但是调试时,是有问题的。