我有这样一种情况,我在我的代码中启动一个进程以设置一个 IPC channel 。我开始的过程是一个不支持 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
被命中。
最佳答案
很遗憾,您从 Process.MainWindowHandle 中获得的值只是一个猜测。程序没有可用的 API 函数来告诉 Windows“这是我的主窗口”。它使用的规则已记录在案,它是进程启动时创建的第一个窗口。如果第一个窗口是登录窗口或初始屏幕,就会造成麻烦。
对此您无能为力,您必须更多地了解程序的行为才能找到真正的主窗口。使用 EnumThreadWindows() 枚举窗口可以帮助您找到它,只要第一个窗口是在与主窗口相同的线程上创建的。如果不是这种情况,则需要更详细的 EnumWindows()。
关于c# - 为什么无法获取已启动进程的主窗口句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4727023/