C# 面板中的压井过程
我有一个Win Forms应用程序,其中我从另一个.exe文件启动一个进程,然后将其句柄属性设置为Win Form应用程序中的一个面板。这将产生Win Forms应用程序内部运行的其他应用程序的效果 以下是我如何做到这一点的:C# 面板中的压井过程,c#,winforms,forms,process,handle,C#,Winforms,Forms,Process,Handle,我有一个Win Forms应用程序,其中我从另一个.exe文件启动一个进程,然后将其句柄属性设置为Win Form应用程序中的一个面板。这将产生Win Forms应用程序内部运行的其他应用程序的效果 以下是我如何做到这一点的: [DllImport("user32.dll", SetLastError = true)] static extern IntPtr SetParent(IntPtr hwc, IntPtr hwp); string exepath = "myProgram.exe"
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hwc, IntPtr hwp);
string exepath = "myProgram.exe";
ProcessStartInfo p = new ProcessStartInfo(exepath);
process = Process.Start(p);
Thread.Sleep(500); //sleep to allow program to start up properly
SetParent(process.MainWindowHandle, pictureBox1.Handle); //then set the handle to give the effect of being run inside the win forms app
现在我知道我可以在FormClosed事件中调用process.Kill(),该事件会在该窗体关闭时终止该进程,但是如果我的Win form应用程序被强制退出,我将如何终止该进程?这可能吗
由于进程的句柄设置为Win Form应用程序中的一个面板,因此它不会显示在任务栏上,但如果未调用process.Kill(),它仍将继续运行,这在Win Form被强制关闭时发生。这意味着每次我都必须通过任务管理器将其关闭,这是一种痛苦
如果这是不可能的,我不会费心设置面板的手柄,我只会让它在一个新窗口中打开
感谢为了确保应用程序一关闭(优雅地或强制地)您的子进程就被正确擦除,您可以使用 作业对象允许将进程组作为一个单元进行管理。工作 对象是可命名、安全、可共享的对象,用于控制 与之关联的进程的属性。进行的手术 在作业对象上影响与该作业对象关联的所有进程。 示例包括强制执行限制,如工作集大小和进程 优先级或终止与作业关联的所有进程
关于StackOverflow,有一个类似的问题,在C#中有一个详细的实现:试试这段代码,我已经用了很长时间了:
public partial class Launcher : Form
{
/// <summary>Collection of process. </summary>
private Dictionary<IntPtr, Process> _processCollection = new Dictionary<IntPtr, Process>();
#region DLL Import
[DllImport("user32.dll")]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
#endregion
/// <summary>Default constructor. </summary>
public Launcher()
{
InitializeComponent();
try {
FormClosing += Launcher_FormClosing;
StartInstances();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
/// <summary>Starts the instances. </summary>
private void StartInstances()
{
var path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
var numberOfInstances = Int32.Parse(ConfigurationManager.AppSettings["NumerOfInstances"]);
for (int i = 0; i < numberOfInstances; i++) {
StartInstance(i, path);
}
}
/// <summary>Starts an instance. </summary>
private void StartInstance(int instanceId, string path)
{
Process proc = Process.Start(path + "\\foo.exe", instanceId.ToString());
IntPtr handlerDocked = IntPtr.Zero;
Panel panel = new Panel();
panel.Size = new Size(flwPanel.Width / 3, flwPanel.Height / 2);
flwPanel.Controls.Add(panel);
do {
try {
proc.WaitForInputIdle(1000); //wait for the window to be ready for input;
proc.Refresh(); //update process info
if (proc.HasExited) {
return; //abort if the process finished before we got a handle.
}
handlerDocked = proc.MainWindowHandle; //cache the window handle
}
catch {
Thread.Sleep(500);
}
} while (handlerDocked == IntPtr.Zero);
//hWndOriginalParent = SetParent(hWndDocked, panel1.Handle);
SetParent(handlerDocked, panel.Handle);
var docked = new DockedElement(handlerDocked, panel);
panel.SizeChanged += new EventHandler(Panel_Resize);
Panel_Resize(docked, new EventArgs());
_processCollection.Add(handlerDocked, proc);
}
private void Panel_Resize(object sender, EventArgs e)
{
var docked = (DockedElement)sender;
//Change the docked windows size to match its parent's size.
MoveWindow(docked.Handle, 0, 0, docked.Container.Width, docked.Container.Height, true);
}
/// <summary>Finallize instances. </summary>
public void FinallizeInstances()
{
foreach (var docked in _processCollection) {
docked.Value.Close();
}
_processCollection.Clear();
}
private void Launcher_FormClosing(object sender, FormClosingEventArgs e)
{
FinallizeInstances();
}
protected override void Dispose(bool disposing)
{
FinallizeInstances();
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
}
公共部分类启动器:表单
{
///过程的集合。
私有字典_processCollection=新字典();
#区域DLL导入
[DllImport(“user32.dll”)]
公共静态外部IntPtr SetParent(IntPtr hWndChild、IntPtr hwndnnewparent);
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部布尔移动窗口(IntPtr hWnd、intx、inty、intnwidth、intnheight、bool bRepaint);
#端区
///默认构造函数。
公共启动器()
{
初始化组件();
试一试{
FormClosing+=启动器\u FormClosing;
起始状态();
}
捕获(例外情况除外){
MessageBox.Show(例如Message);
}
}
///启动实例。
私有无效起始状态()
{
var path=System.IO.path.GetDirectoryName(Assembly.getExecutionGassembly().GetName().CodeBase);
var numberOfInstances=Int32.Parse(ConfigurationManager.AppSettings[“numberOfInstances]”);
对于(int i=0;i