我需要启动一些 Windows 应用程序以在表单内运行。我正在使用 VS-15 IDE 在 C# 上开发 Windows 桌面应用程序。
很多年前就已经解决了这个话题。这是我找到的最佳答案:
How can I run another application within a panel of my C# program?
但是所有示例都涉及启动记事本,它工作正常。我确实可以以目标形式在目标面板内启动和运行记事本,并且运行完美。
但我不需要启动记事本,我需要启动其他已安装的应用程序,并且发现无法在目标面板/表单中启动所需应用程序的令人沮丧的现实。它只是在表单外打开。
甚至找到了一个帖子,其中一个OP需要启动IE,但是同样的结果,IE在窗体之外启动。
阅读和阅读相关主题,我发现它可能是使用名为 EnumWindows 的东西解决的可能性。我真的是 C# 的新手,我通常与 Python 打交道。我什至不是 Windows 的原生用户,不得不将其安装在 VM 中。
我使用的是 Visual Studio 2015。预期输出是 Windows 7 和 8 计算机的桌面应用程序,64 位。
代码:
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace < >
{
public partial class Form1:
{
private void btn_qui_Click(object sender, EventArgs e)
{
var postventa = new appUser("POSTVENTA", "",3);
try
{
frm_3.Show();
Process p = Process.Start("C://QuiterWeb/QuiterWeb.exe");
p.WaitForInputIdle();
SetParent(p.MainWindowHandle, frm_3.panel_3.Handle);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
运行代码时,.exe 在窗体外打开。但是,如果我改为打开 notepad.exe,它会在特定面板和表单中打开。这表明目标已很好地映射到方法。
这里有什么问题?如何让.exe在面板和窗体中运行?
最佳答案
这取决于你的具体过程。它在空闲时可能没有主窗口句柄(这种情况不常见,但可能会发生),或者它可能有多个“主窗口”。
等待进程拥有其第一个 MainWindowHandle
的正确方法应该是这样的:
Process p = Process.Start("C://QuiterWeb/QuiterWeb.exe");
p.WaitForInputIdle();
while (p.MainWindowHandle == IntPtr.Zero)
{
Thread.Sleep(100); // Don't hog the CPU
p.Refresh(); // You need this since `MainWindowHandle` is cached
// do additional checks, or add a timeout in case the process is stalled
// or never creates a main window handle, etc.
}
SetParent(p.MainWindowHandle, frm_3.panel_3.Handle);
如果您的进程实际上生成了多个“主窗口”,那么您需要对其进行篡改(等待第二个 MainWindowHandle
)
至于你的具体问题,EnumWindows
只是列出了进程产生的窗口...如果你的进程有多个窗口并且你想将它们全部托管在 winforms 中,这可能很有用,但它几乎是特定于流程的(您更有可能还需要 EnumChildWindows
或 EnumThreadWindows
并枚举所有流程以制作通用的东西,以及特定的需求如果您需要在自己的窗口中托管窗口,则需要特定的 UI。
关于c# - 使用 EnumWindows 在 WinForm 的面板内启动 .exe 应用程序 - 而不是记事本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35858788/