【问题标题】:Why do I have to create a separate task to run a process here?为什么我必须创建一个单独的任务来在这里运行一个进程?
【发布时间】:2014-03-06 13:48:37
【问题描述】:

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

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

【问题讨论】:

  • TaskCreationOptions.AttachedToParent 需要附加一个父任务。
  • @usr 如果您阅读本文,您会找到所有问题的答案。应用程序正常工作,但在所描述的情况下,系统无法启动该进程并通过来自 CSRSS.exe 的错误消息窗口告知它。不幸的是,我无法缩短这篇文章。

标签: c# multithreading winapi


【解决方案1】:

我将this 拍打在一起以尝试重现您的错误,但两次调用都可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多