启动进程而不窃取焦点 (C#)
我需要能够启动进程(控制台和窗口)而不窃取焦点。我发现在 .NET 框架中执行此操作的唯一方法是 Microsoft.VisualBasic.Interaction.Shell 和 Microsoft.VisualBasic.AppWinStyle.[Minimized|Normal]NoFocus (映射到 SW_SHOWMINNOACTIVE/SW_SHOWMA 并传递到 ShellExecute)。
在我的代码的当前版本(确实抢走了焦点)中,我正在使用 System.Diagnostics.Process,并依赖于为我提供的一些功能,而 Interaction.Shell 方法则没有。
2 个问题(一个是严肃的,一个是发泄我的挫败感,我真的不希望得到一个好的答案)
1.)我别无选择,只能自己包装 CreateProcess 或 ShellExecuteEx,这是否正确,或者我是否缺少其他解决方案?我真的希望避免这种情况,因为 Process 是一个完整且有用的包装器,除了这种疏忽之外,而且还有很多功能需要实现、P/Invoke 调用调试以及各种痛苦。
2.) 为什么 Microsoft 的一个团队会创建这样一个(否则)完整的包装器,然后从 ProcessWindowStyle 中排除一半可能的值,而另一个团队创建一个类似的包装器,虽然不太完整,但提供了所有有用的窗口样式?
I need to be able to start processes (both console and windowed) without it stealing focus. The only way within the .NET framework that I found to do this is Microsoft.VisualBasic.Interaction.Shell with Microsoft.VisualBasic.AppWinStyle.[Minimized|Normal]NoFocus (which map to SW_SHOWMINNOACTIVE/SW_SHOWMA being passed through to ShellExecute).
In the current version of my code (which does steal focus), I am using System.Diagnostics.Process, and relying on some of the functionality that gives me, which the Interaction.Shell method does not.
2 questions (one serious, and one venting my frustration that I don't really expect a good answer to)
1.) Am I correct that I have no choice but to wrap CreateProcess or ShellExecuteEx myself, or am I missing some other solution? I was really hoping to avoid this, as Process is such a complete and useful wrapper other than this oversight, and there would be so much functionality to implement, P/Invoke calls to debug, and all sorts of assorted pain.
2.) Why would one team at Microsoft create such a (otherwise) complete wrapper, and then exclude half of the possible values from ProcessWindowStyle, while another team created a similar wrapper that was much less complete, but provided all the useful window styles?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
VB.Net 团队做了很多工作来简化开发人员在 Windows 仪表方面的工作,我认为添加对 VB dll 的引用并在 C# 程序中使用它没有问题。
只是两个团队的侧重点不同,仅此而已。如果使用 Microsoft.VisualBasic.Interaction.Shell 解决了您的问题,您不应该感到难过。
如果您不想引用dll,也可以使用Reflector查看实际实现并自己实现代码。
[编辑 - 在注释后添加代码示例以显示您可以组合 Interaction.Shell 和 Process]
这里我使用 Shell 方法来启动进程,从 pid 获取进程的句柄,然后挂钩关于事件。您甚至可以执行 p.Kill() 来中止该进程。
[编辑 - cmd.exe 的解决方法]
根据我的口味,它开始变得有点老套,但它确实有效。将“NEWWINDOW”替换为随机引导或其他内容以使其独一无二。
The VB.Net team has done much more to ease things for the developer regarding instrumentation of windows, and I see no problem adding a reference to a VB dll and use that in your C# program.
It's two teams with different focus, that's all. And you shouldn't feel bad about using Microsoft.VisualBasic.Interaction.Shell if it solves your issue.
You can also use Reflector to see the actual implementation and implement the code yourself if you don't want to reference the dll.
[Edit - added code example after comment to show you can combine Interaction.Shell and Process]
Here I use the Shell method to kick off the process, get a handle to the process from the pid, and hook on events. You can even do p.Kill() in order to abort the process.
[Edit - workaround for cmd.exe]
It's starting to become a bit hackish to my taste, but it works. Replace "NEWWINDOW" with a random guid or something to make it unique.
看一下这里:
编辑:我修改了代码以显示引发事件和处理事件的方法,此外,我还展示了
Handle
属性的用法,它是正在运行的进程的句柄。Have a look here:
Edit: I have modified the code to show the means of raising events and handling them, also, I have shown the usage of the
Handle
property which is the handle of the process that is running.