从Windows 7中的Windows服务启动交互式进程

时间:2013-11-28 13:39:05

标签: c# windows visual-studio winapi service

我正在尝试从Windows服务启动交互式进程。 如你所知,这在Windows 7中很棘手,因为服务在另一个会话中运行,但我知道它是可能的:

http://blogs.msdn.com/b/winsdk/archive/2009/07/14/launching-an-interactive-process-from-windows-service-in-windows-vista-and-later.aspx

        IntPtr hToken2 = IntPtr.Zero;
       //   WTSQueryUserToken(WTSGetActiveConsoleSessionId(), out userToken);
        WTSQueryUserToken(1, out userToken);

userToken为0.如果我将sessionId硬编码为1,则userToken不为0,但进程未启动(该服务不会抛出任何错误)

        IntPtr newToken = IntPtr.Zero;
        SECURITY_ATTRIBUTES tokenAttributes = new SECURITY_ATTRIBUTES();
        tokenAttributes.nLength = Marshal.SizeOf(tokenAttributes);
        SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
        threadAttributes.nLength = Marshal.SizeOf(threadAttributes);
       if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
            TOKEN_TYPE.TokenImpersonation, out newToken))
        {
            throw new Exception("ERROR: DuplicateTokenEx returned false - " + Marshal.GetLastWin32Error());
        }
        TOKEN_PRIVILEGES tokPrivs = new TOKEN_PRIVILEGES();
        tokPrivs.PrivilegeCount = 1;
        LUID seDebugNameValue = new LUID();
        if (!LookupPrivilegeValue(null, SE_DEBUG_NAME, out seDebugNameValue))
        {
            throw new Exception("ERROR: LookupPrivilegeValue returned false - " + Marshal.GetLastWin32Error());
        }
        tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1];
        tokPrivs.Privileges[0].Luid = seDebugNameValue;
        tokPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

        if (!AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero))
        {
            throw new Exception("ERROR: AdjustTokenPrivileges returned false - " + Marshal.GetLastWin32Error());
        }
        PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
        STARTUPINFO si = new STARTUPINFO();
        si.cb = Marshal.SizeOf(si);

       // si.lpDesktop = "Winsta0\\Winlogon";
        si.lpDesktop = string.Empty;
        if (!CreateProcessAsUser(newToken, "calc.exe", null, ref tokenAttributes, ref threadAttributes,
            true, (int)CreateProcessFlags.CREATE_NEW_CONSOLE | (int)CreateProcessFlags.INHERIT_CALLER_PRIORITY, IntPtr.Zero,
            "C:\\Windows\\System32", ref si, out pi))
        {
            throw new Exception ("ERROR: CreateProcessAsUser returned false - " + Marshal.GetLastWin32Error());
        }

我的服务没有启动任何进程。如果我使用createprocess它会启动该过程,但它不在交互式桌面上。

编辑:

我设法使用此代码启动交互式程序。我将lpDesktop修改为string.empty。

现在问题仍然存在:   - 如何在winlogon上启动它?甚至更好......在系统帐户上。 当我在Session 0(服务所在的位置)上启动程序时,程序在系统帐户上运行(显而易见),但在会话1上运行时,它在用户帐户上运行。

0 个答案:

没有答案