为了简单起见,我正在编写一个调用“APPLICATION A”的程序,它打开了一个到本地主机上的端口8881的套接字连接;之后它使用代码打击产生了一个exe应用程序调用“APPLICATION B”:
try
{
XmSam.Log("Spawning (" + process + ")");
ProcessEx proc = new ProcessEx();
proc.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + process + ".exe";
proc.StartInfo.Arguments = parameters;
proc.StartInfo.UseShellExecute = false;
proc.Start();
Program.Processes.Add(proc);
XmSam.Log("Spawned " + proc.ProcessName);
}
catch (Exception ex)
{
XmSam.Log(ex);
}
当我关闭APPLICATION A时(通过停止应用程序或在窗口任务管理器中终止其进程),APPLICATION B仍然运行,这很好。但是,当我再次启动APPLICATION A时,我得到了例外:
2012-10-18 16:21:23 - Only one usage of each socket address (protocol/network address/port) is normally permitted
2012-10-18 16:21:23 - at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
当APPLICATION A试图打开套接字到端口8881时发生了这个错误。如果我杀死APPLICATION B,这个错误就会消失。我不认为这是因为APPLICATION B代码,因为它没有任何代码如下面的代码所示:
[STAThread]
static void Main()
{
while (true)
{
}
}
我试着在Process类下查看MSDN,但我没有看到任何相关内容。我假设当你生成一个进程时,该进程独立于调用应用程序,但显然情况并非如此。你知道任何让我在不调用调用应用程序的情况下生成进程的设置吗?
我知道另一种方法是在APPLICATION A中使用代码来杀死APPLICATION B,但这不是理想的解决方案,特别是在APPLICATION A意外崩溃的情况下。
谢谢。
答案 0 :(得分:0)
应该确保应用程序A在关闭时关闭套接字。我认为Application.ApplicationExit Event是一个很好的地方,或者当你完成套接字时。
答案 1 :(得分:0)
经过多次挖掘后,我找到了答案。我觉得这很棒article
其中,该问题的主要解释如下:
System.Diagnostics.Process.Start使子进程从父进程继承句柄。这意味着,无论您生成什么进程(例如Internet Explorer),该进程都会获取您的进程拥有的所有句柄!因此,即使你在进程中释放句柄,如果你生成的进程仍在运行,你的句柄也不会被释放,因为子进程可能正在使用它们。
因此,考虑到这一点,我所要做的就是将UseShellExecute标志更新为true。
proc.StartInfo.UseShellExecute = true;