我有一个控制台应用程序试图以这种方式创建一个进程:
public static void Main(string[] args)
{
const string path = @"C:\Windows\system32\notepad.exe";
const string param = "";
Task.Factory.StartNew(() =>
{
Process pp = CreateProcessAsUser(path, param);
pp.WaitForExit();
},
TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
Console.ReadLine();
}
如果我运行它,CSRSS.exe会显示一个窗口,其中显示错误消息:“应用程序无法正确启动(0xc0000142)”。如果我将其更改为以下代码,一切正常:
Task.Factory.StartNew(() =>
{
Task task = Task.Factory.StartNew(() =>
{
Process pp = CreateProcessAsUser(path, param);
pp.WaitForExit();
});
task.Wait();
},
TaskCreationOptions.AttachedToParent | TaskCreationOptions.LongRunning);
你有什么想法吗?
以下是CreateProcessAsUser的代码:
public static Process CreateProcessAsUser(string filename, string args)
{
IntPtr hToken = WindowsIdentity.GetCurrent().Token;
IntPtr hDupedToken = IntPtr.Zero;
ProcessInformation pi = new ProcessInformation();
SecurityAttributes sa = new SecurityAttributes();
sa.Length = Marshal.SizeOf(sa);
DuplicateTokenEx(hToken,
genericAllAccess,
ref sa,
(int)SecurityImpersonationLevel.SecurityIdentification,
(int)TokenType.TokenPrimary,
ref hDupedToken);
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = string.Empty;
string path = Path.GetFullPath(filename);
using (WindowsIdentity.Impersonate(IntPtr.Zero))
{
CreateProcessAsUser(hDupedToken,
path,
string.Format("\"{0}\" {1}", filename.Replace("\"", "\"\""), args),
ref sa,
ref sa,
false,
0,
IntPtr.Zero,
@".\",
ref si,
ref pi);
}
return Process.GetProcessById(pi.dwProcessID);
}
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern bool CreateProcessAsUser(...)