【发布时间】:2011-06-11 06:03:45
【问题描述】:
我有一种情况,我在我的代码中启动一个进程以设置 IPC 通道。我开始的进程是一个不支持 CLR 的 MFC 应用程序。我开始此过程的应用程序是 WPF 应用程序中的 C# 模块(我认为这与我的问题无关)。这适用于支持 CLR 的应用程序版本,并且它适用于除部署目标(装有 Windows 7 的触摸屏计算机)之外的每台计算机。但由于某种原因,当我在这个确切的场景中尝试它时,进程对象永远不会解析主窗口句柄 (Process.MainWindowHandle)。是否有另一种(甚至可能是 pinvoke)方法来做到这一点?这是安全问题吗?我是那个盯着这个过程的人。进程的主窗口句柄确实存在。我看不出有什么问题。
如果有帮助,这是我的代码。
_applicationProcess = new Process();
_applicationProcess.StartInfo.FileName = _strProcessPath;
_applicationProcess.StartInfo.Arguments = _strProcessArguments;
_applicationProcess.Start();
long nTicks = Environment.TickCount;
if (_applicationProcess.WaitForInputIdle(1 /*minute(s)*/ * 60000))
{
try
{
do
{
// Don't let total processing take more than 1 minute(s).
if (Environment.TickCount > nTicks + 1 /*minute(s)*/ * 60000)
throw new ApplicationException("MFCApplication.Startup failed! The main window handle is zero!");
_applicationProcess.Refresh();
}
while (_applicationProcess.MainWindowHandle.ToInt32() == 0);
_applicationHandle = new IntPtr(_applicationProcess.MainWindowHandle.ToInt32());
}
catch (Exception ex)
{
//Do some stuff...
throw;
}
}
else
{
// Do exception handling.
}
在尝试获取非零的主窗口句柄一分钟后,ApplicationException 被击中。
【问题讨论】:
-
您是否厌倦了按照 MSDN 文档的建议使用
WaitForInputIdle?此外,最好使用throw而不是throw ex,因为throw ex会丢失堆栈跟踪信息(throw ex重新启动异常抛出并因此重新启动堆栈跟踪)。 -
@jordan 我看到了你的编辑。您需要在您的 cmets 中包含 @username,以便通知您正在回复的其他用户。
-
@jordan 在您的 do\while 循环中,我认为您将滴答声与毫秒混淆了。一个滴答声是 100 纳秒。为此使用
Stopwatch可能更直接。 -
@jordan 可能值得考虑在你的循环中加入一个
Thread.Sleep来限制你的Refresh调用。 -
@chibacity 不,这些都不起作用。而且我认为 @ 没有必要,因为你是唯一的评论者。