我正在调用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,那么问题就会出现问题。
在没有调试器的情况下执行应用程序时,不会引发问题。
答案 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";
}
调用StartWithPath
和StartWithInfo
来阻止我在控制台应用中的线程。我的控制台没有显示&#34; Process Started&#34;直到Excel启动屏幕关闭并且主窗口打开后。
StartInNewThread
会立即在控制台上显示这两条消息,而Excel的初始屏幕仍处于打开状态。
答案 3 :(得分:0)
我们在启动位于不同域(我们有双受信任域)的网络驱动器上的.bat脚本时遇到此问题。我运行了一个远程C#调试器,确定Process.Start()无限期地阻塞。
在power shell中以交互方式重复此任务时,会弹出一个安全对话框:
就解决方案而言,this was the direction我们去了。完成工作的人修改了域GPO以实现信任。
答案 4 :(得分:0)
通过命令提示符启动服务器:
"C:\Program Files (x86)\IIS Express\iisexpress" /path:\Publish /port:8080
这可以访问OS的树进程的子线程。