如何启动进程并使其主窗口模式化到启动进程的窗口?
我有一个 C# WinForms 程序,它启动另一个进程。然后程序等待,直到进程完成。
目前我使用 Process.WaitForExit(),但这意味着当我的程序等待 Process 结束时,它不会重新绘制并且“看起来”没有响应。
有什么方法可以让我的程序启动的进程窗口成为我的主窗体的模式(即您无法切换回我的程序并且窗口重新绘制)?
基本上我想做一些类似 Form.ShowDialog() 的事情,除了使用进程的窗口作为要显示为对话框的表单。
I have a C# WinForms program thats starts another Process. The program then waits until the Process has finished.
Currently I use Process.WaitForExit(), but this means that while my program waits for the Process to end, it doesn't repaint and "looks" like it's not responding.
Is there any way for the Window of the Process that my program starts, be modal to my main form (i.e. you can't switch back to my program & the window repaints)?
Basically I want to do something like Form.ShowDialog(), except using the Process's Window as the Form to be shown as a dialog.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
为什么不在单独的线程中启动进程?这样,只有您的线程会等待。这样,您的表单仍然会做出响应。
Why don't you start your process in a separate thread? That way, only your thread will wait. This way, your form will still respond.
您无法阻止用户切换回来,因为您已经生成了一个单独的进程。就操作系统而言,就好像您通过桌面图标启动了第二个操作系统(例如)。
我认为您最好的希望是在第二个进程处于活动状态时禁用相关菜单/选项。您需要继续轮询以查看它是否仍然存在,否则您的主应用程序将变得无法使用。
另一种方法可能是最小化主应用程序,这将使其不受影响。
You can't prevent the user from switching back because you've spawned a separate process. As far as the operating system is concerned it's as if you'd started the second one via it's desktop icon (for example).
I think the best you can hope for is to disable the relevant menus/options when the second process is active. You'll need to keep polling to see if it's still alive, otherwise your main application will become unusable.
Another approach might be to minimize the main application which will keep it out of the way.
创建表单,显示模式。
然后使用BackgroundWorker启动进程并处理RunWorkerCompleted事件以关闭表单。
Create Form, Show it modal.
then use BackgroundWorker to start process and handle RunWorkerCompleted event to close the form.
您可以创建另一种形式,使其成为模态形式。在该表单加载上,您将调用
Visible = false;
然后您将启动一个线程来启动您的进程并等待它通过该线程完成。然后在等待完成后从线程内执行
BeginInvoke(new MethodInvoker(delegate { Close(); } ));
。You could create another form which you make modal. On that form load you would call
Visible = false;
then you would start a thread which starts your process and waits for it to finish via the thread.Then do a
BeginInvoke(new MethodInvoker(delegate { Close(); } ));
from within the thread after the wait for complete finishes.您绝对应该创建一个新线程,并从该线程启动您要启动的应用程序。这将使您的应用程序做出响应,即使其他应用程序正在运行
You should definately create a new thread and from that thread, launch the application you are trying to launch. This will make your application responsive, even while the other application is running
据我所知,这是不可能的。您可以使用 SetParent(非托管)来设置子/父关系,但这是您所能做到的。注意:我使用的是基于 perl 的程序,而 SetParent() 例程似乎并不像宣传的那样工作。
To the best of my knowledge, this isn't possible. You can use SetParent (unmanaged) to set the child / parent relationship, but that is as far as you can go. Note: I'm using a perl based program and the SetParent() routine doesn't seem to work as advertised.
另一种方法有点不标准,但它有效。定义变量 ProcessActive。在应用程序中可见的每个控件上,检查变量,如果设置,则不处理控件事件。在启动流程之前,将 ProcessActive 变量设置为 True 并使用事件启动流程。在进程上定义 Exited 事件,以便将 ProcessActive 设置为 False。他们可以切换回启动应用程序,一切看起来都很好。在进程退出之前它不会执行任何操作。您可能希望将光标设置为沙漏,以便他们知道应用程序正忙。
Another way that is a little non-standard but it works. Define a variable ProcessActive. On each of the controls visible in the app, check the variable and if set, don't process the controls event. Before launching the process, set the ProcessActive variable to True and launch the process with events. Define the Exited event on the process so that it sets the ProcessActive to False. They can switch back to the launching application and everything looks good. It just won't do anything until the process has exited. You might want to set the cursor to the hourglass so they know that the app is busy.