[英]Process.Start is blocking
我正在调用 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 停止服务 --- 启动进程。
找到了:
[STA线程]
使 Process.Start 阻塞。 我阅读了STAThread 和 Multithreading ,但我无法将这些概念与 Process.Start 行为联系起来。
AFAIK,Windows.Form需要STAThread。 使用 Windows.Form 时如何解决此问题?
地狱新闻:
如果我重建我的应用程序,我第一次运行应用程序工作正常,但如果我停止调试并再次重新启动,问题就会出现。
在没有调试器的情况下执行应用程序时不会出现问题。
不, 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");
}
}
这会在我的盒子上打印“看,我还在跑步”,而我的盒子没有问题 - 它在你的盒子上做了什么?
创建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}.");
}
我遇到了同样的问题,直接从可执行文件创建进程启动可执行文件解决了这个问题。
我在 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
的调用会阻止我在控制台应用程序中的线程。 在 Excel 初始屏幕关闭且主窗口打开之前,我的控制台不会显示“进程已启动”。
StartInNewThread
将立即在控制台上显示这两条消息,而 Excel 的初始屏幕仍处于打开状态。
我们在启动位于不同域的网络驱动器上的 .bat 脚本时遇到了这个问题(我们有两个受信任的域)。 我运行了一个远程 C# 调试器,果然 Process.Start() 无限期地阻塞了。
在 power shell 中以交互方式重复此任务时,会弹出一个安全对话框:
就解决方案而言, 这是我们前进的方向。 完成工作的人修改了域 GPO 以完成信任。
通过命令提示符启动服务器:
"C:\Program Files (x86)\IIS Express\iisexpress" /path:\Publish /port:8080
这可以访问操作系统树进程的子线程。
如果要启动进程,然后使进程独立于“启动器”/发起调用:
//Calling process
using (System.Diagnostics.Process ps = new System.Diagnostics.Process())
{
try
{
ps.StartInfo.WorkingDirectory = @"C:\Apps";
ps.StartInfo.FileName = @"C:\Program Files\Microsoft Office\Office14\MSACCESS.EXE"; //command
ps.StartInfo.Arguments = @"C:\Apps\xyz.accdb"; //argument
ps.StartInfo.UseShellExecute = false;
ps.StartInfo.RedirectStandardOutput = false;
ps.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
ps.StartInfo.CreateNoWindow = false; //display a windows
ps.Start();
}
catch (Exception ex)
{
MessageBox.Show(string.Format("==> Process error <=={0}" + ex.ToString(), Environment.NewLine));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.