Я пытаюсь запустить приложение лотка графического интерфейса из службы Windows (LocalSystem) с помощью createProcessasUser - вот так:
public static System.Diagnostics.Process StartProcessInSession(int sessionID, String commandLine)
{
IntPtr userToken;
if (WTSQueryUserToken(sessionID, out userToken))
{
//note that WTSQueryUserToken only works when in context of local system account with SE_TCB_NAME
IntPtr lpEnvironment;
if (CreateEnvironmentBlock(out lpEnvironment, userToken, false))
{
StartupInfo si = new StartupInfo();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = "winsta0\\default";
si.dwFlags = STARTF.STARTF_USESHOWWINDOW;
si.wShowWindow = ShowWindow.SW_SHOW;
ProcessInformation pi;
if (CreateProcessAsUser(userToken, null, new StringBuilder(commandLine), IntPtr.Zero, IntPtr.Zero, false, CreationFlags.CREATE_NEW_CONSOLE | CreationFlags.CREATE_UNICODE_ENVIRONMENT, lpEnvironment, null, ref si, out pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
//context.Undo();
try
{
return System.Diagnostics.Process.GetProcessById(pi.dwProcessId);
}
catch (ArgumentException e)
{
//The process ID couldn't be found - which is what always happens because it has closed
return null;
}
}
else
{
int err = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(err, "Could not create process.\nWin32 error: " + err.ToString());
}
}
else
{
int err = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(err, "Could not create environment block.\nWin32 error: " + err.ToString());
}
}
else
{
int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
if (err == 1008) return null; //There is no token
throw new System.ComponentModel.Win32Exception(err, "Could not get the user token from session " + sessionID.ToString() + " - Error: " + err.ToString());
}
}
Я использую функцию так:
protected override void OnStart(string[] args)
{
_agentProcess = StartProcessInSession(WTSGetActiveConsoleSessionId(), "Some_correct_path");
}
Это действительно работало какое-то время, но в одном из моих запусков оно внезапно перестало работать... выдавая следующую ошибку при выполнении команды CreateProccessAsUser (не могу углубиться)
{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}
Я понятия не имею, почему это происходит или даже как отлаживать это дальше, во всяком случае, есть идеи ?? потому что это не имеет для меня никакого смысла.
Создать процесс как определение пользователя:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, [In] StringBuilder lpCommandLine, IntPtr /*to a SecurityAttributes struct or null*/ lpProcessAttributes, IntPtr /*to a SecurityAttributes struct or null*/ lpThreadAttributes, bool bInheritHandles, CreationFlags creationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref StartupInfo lpStartupInfo, out ProcessInformation lpProcessInformation);
Спасибо
lpEnvironment
допустимым указателем? ИuserToken
действительныйHANDLE
? - person Ben Voigt   schedule 09.01.2012CreateProcessAsUser
? - person David Heffernan   schedule 09.01.2012