我試過這篇文章Code Project,它對我來說工作正常。 我也使用過這些代碼。文章在屏幕截圖中很好解釋。
我加入必要的解釋,這種情況下
您剛纔啓動您的計算機,並即將登錄。登錄時,系統會爲您分配唯一的會話ID。在Windows Vista中,第一個登錄到計算機的用戶被操作系統分配的會話ID爲1。下一個要登錄的用戶將被分配一個會話ID 2.等等等等。您可以從任務管理器中的用戶選項卡查看分配給每個登錄用戶的會話ID。
但是,您的Windows服務被帶到會話ID爲0之下。此會話與其他會話隔離。這最終阻止Windows服務調用在用戶會話的1或2下運行的應用程序。
爲了從Windows服務調用應用程序,您需要從winlogon.exe複製控件,該控件作爲當前登錄用戶,如圖所示在下面的截圖。
重要代碼
// obtain the process id of the winlogon process that
// is running within the currently active session
Process[] processes = Process.GetProcessesByName("winlogon");
foreach (Process p in processes)
{
if ((uint)p.SessionId == dwSessionId)
{
winlogonPid = (uint)p.Id;
}
}
// obtain a handle to the winlogon process
hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
// obtain a handle to the access token of the winlogon process
if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
{
CloseHandle(hProcess);
return false;
}
// Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
// I would prefer to not have to use a security attribute variable and to just
// simply pass null and inherit (by default) the security attributes
// of the existing token. However, in C# structures are value types and therefore
// cannot be assigned the null value.
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.Length = Marshal.SizeOf(sa);
// copy the access token of the winlogon process;
// the newly created token will be a primary token
if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
(int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup))
{
CloseHandle(hProcess);
CloseHandle(hPToken);
return false;
}
STARTUPINFO si = new STARTUPINFO();
si.cb = (int)Marshal.SizeOf(si);
// interactive window station parameter; basically this indicates
// that the process created can display a GUI on the desktop
si.lpDesktop = @"winsta0\default";
// flags that specify the priority and creation method of the process
int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
// create a new process in the current User's logon session
bool result = CreateProcessAsUser(hUserTokenDup, // client's access token
null, // file to execute
applicationName, // command line
ref sa, // pointer to process SECURITY_ATTRIBUTES
ref sa, // pointer to thread SECURITY_ATTRIBUTES
false, // handles are not inheritable
dwCreationFlags, // creation flags
IntPtr.Zero, // pointer to new environment block
null, // name of current directory
ref si, // pointer to STARTUPINFO structure
out procInfo // receives information about new process
);
據我可以告訴有什麼錯書面,你得到一個異常的代碼? –
告訴我們你運行這個程序時發生了什麼? – NT88