为什么我必须创建一个单独的任务来运行进程?

时间:2014-03-06 13:48:37

标签: c# multithreading winapi

我有一个控制台应用程序试图以这种方式创建一个进程:

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(...)

1 个答案:

答案 0 :(得分:1)

我打了this一起试图重现你的错误,但两次调用都能正常工作。