Process.Start正在阻止

时间:2010-06-19 19:22:41

标签: c# process blocking sta

我正在调用Process.Start,但它会阻止当前线程。

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");

// Start process
mProcess = new Process();
mProcess.StartInfo = pInfo;
if (mProcess.Start() == false) {
    Trace.TraceError("Unable to run process {0}.");
}

即使进程已关闭,代码也不再响应。

但是Process.Start真的应该阻止吗?发生了什么事?

(流程正确启动)


using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;

namespace Test
{
    class Test
    {
        [STAThread]
        public static void Main()
        {
            Thread ServerThread = new Thread(AccepterThread);
            ServerThread.Start();

            Console.WriteLine (" ---  Press ENTER to stop service ---");
            while (Console.Read() < 0) { Application.DoEvents(); }

            Console.WriteLine("Done.");
        }

        public static void AccepterThread(object data)
        {
            bool accepted = false;

            while (true) {
                if (accepted == false) {
                    Thread hThread = new Thread(HandlerThread);
                    accepted = true;
                    hThread.Start();
                } else
                    Thread.Sleep(100);
            }
        }

        public static void HandlerThread(object data)
        {
            ProcessStartInfo pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");

            Console.WriteLine("Starting process.");

            // Start process
            Process mProcess = new Process();
            mProcess.StartInfo = pInfo;
            if (mProcess.Start() == false) {
                Console.WriteLine("Unable to run process.");
            }
            Console.WriteLine("Still living...");
        }
    }
}

控制台输出为:

  

---按ENTER键停止服务---   启动过程。


找到它:

[STAThread]

使Process.Start阻止。我读过STAThread and Multithreading,但我无法将这些概念与Process.Start行为联系起来。

Windows.Form的AFAIK,STAThread 必需。如何在使用Windows.Form?

时解决此问题

地狱新闻:

如果我重建我的应用程序,第一次时间我运行应用程序正常工作,但是如果我再次停止调试并重新启动iy,那么问题就会出现问题。

在没有调试器的情况下执行应用程序时,不会引发问题。

5 个答案:

答案 0 :(得分:10)

不,Process.Start不等待子进程完成...否则您将无法使用重定向I / O等功能。

示例控制台应用:

using System;
using System.Diagnostics;

public class Test
{
    static void Main()
    {
        Process p = new Process { 
            StartInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe")
        };
        p.Start();
        Console.WriteLine("See, I'm still running");
    }
}

打印出“看,我还在跑”,我的盒子上没有任何问题 - 它在盒子上做了什么?

答案 1 :(得分:7)

创建ProcessStartInfo并将UseShellExecute设置为false(默认值为true)。您的代码应为:

pInfo = new ProcessStartInfo("C:\\Windows\\notepad.exe");
pInfo.UseShellExecute = false;

// Start process
mProcess = new Process();
mProcess.StartInfo = pInfo;
if (mProcess.Start() == false) {
    Trace.TraceError("Unable to run process {0}.");
}

我有同样的问题,直接从可执行文件启动可执行文件创建过程解决了这个问题。

答案 2 :(得分:1)

我遇到了与WinForms应用程序中的原始海报相同的阻止行为,因此我在下面创建了控制台应用程序以简化测试此行为。

Jon Skeet的例子使用记事本,只需几毫秒即可正常加载,因此线程块可能会被忽视。我试图启动Excel,这通常需要更长的时间。

using System;
using System.Diagnostics;
using static System.Console;
using System.Threading;

class Program {

    static void Main(string[] args) {

        WriteLine("About to start process...");

        //Toggle which method is commented out:

        //StartWithPath();  //Blocking
        //StartWithInfo();  //Blocking
        StartInNewThread(); //Not blocking

        WriteLine("Process started!");
        Read();
    }

    static void StartWithPath() {
        Process.Start(TestPath);
    }

    static void StartWithInfo() {
        var p = new Process { StartInfo = new ProcessStartInfo(TestPath) };
        p.Start();
    }

    static void StartInNewThread() {
        var t = new Thread(() => StartWithPath());
        t.Start();
    }

    static string TestPath =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop) +
        "\\test.xlsx";
}

调用StartWithPathStartWithInfo来阻止我在控制台应用中的线程。我的控制台没有显示&#34; Process Started&#34;直到Excel启动屏幕关闭并且主窗口打开后。

enter image description here

StartInNewThread会立即在控制台上显示这两条消息,而Excel的初始屏幕仍处于打开状态。

答案 3 :(得分:0)

我们在启动位于不同域(我们有双受信任域)的网络驱动器上的.bat脚本时遇到此问题。我运行了一个远程C#调试器,确定Process.Start()无限期地阻塞。

在power shell中以交互方式重复此任务时,会弹出一个安全对话框:

enter image description here

就解决方案而言,this was the direction我们去了。完成工作的人修改了域GPO以实现信任。

答案 4 :(得分:0)

通过命令提示符启动服务器:

"C:\Program Files (x86)\IIS Express\iisexpress" /path:\Publish /port:8080

这可以访问OS的树进程的子线程。