Visual Basic.NET 7.x (2002/03)Visual Basic 9 (2008)Visual Basic 8 (2005)质量保证 (QA)Windows VistaWin32Visual Studio 2008Visual Studio 2005Windows XPC# 2.0C# 3.0中级开发Visual StudioWindowsVisual BasicC#
父进程窗口






3.50/5 (4投票s)
演示如何获取进程 ID 并在父进程窗口上显示模态窗口。
引言
本文展示了如何针对父进程窗口显示模态对话框/窗体。
下载文件包含一个演示解决方案,展示了如何使用此处显示的所有代码。
重要的代码被封装在一个类中,这使得维护工作更容易!
背景
这种情况并不经常发生,但我最近需要创建一个 Windows 服务,该服务需要在安装过程中显示一个对话框窗口以收集一些用户信息。在开发安装项目的过程中,我开始思考如何确保数据收集窗体不被隐藏,并且在用户未完成必要细节的情况下,安装不会继续进行。
我记得过去曾使用 MFC 和 WIN32 做过类似的事情,但这次我需要针对基于 .NET 的解决方案。我决定做一些研究。
在 CodeProject 资源中,我找到了一个解决方案,它展示了如何使用 WIN32 获取父进程,并且我还找到了将 IntPtr
句柄封装到 IWin32Window
中的方法!
这是将检索父进程的函数
Process GetParentProcess()
{
int iParentPid = 0;
int iCurrentPid = Process.GetCurrentProcess().Id;
IntPtr oHnd = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(oHnd == IntPtr.Zero)
return null;
PROCESSENTRY32 oProcInfo = new PROCESSENTRY32();
oProcInfo.dwSize =
(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(PROCESSENTRY32));
if(Process32First(oHnd, ref oProcInfo) == false)
return null;
do
{
if(iCurrentPid == oProcInfo.th32ProcessID)
iParentPid = (int)oProcInfo.th32ParentProcessID;
}
while(iParentPid == 0 && Process32Next(oHnd, ref oProcInfo));
if(iParentPid > 0)
return Process.GetProcessById(iParentPid);
else
return null;
}
这是 PInvoke 定义
#region WIN32 Definitions
static uint TH32CS_SNAPPROCESS = 2;
[StructLayout(LayoutKind.Sequential)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
};
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateToolhelp32Snapshot(uint dwFlags, uint th32ProcessID);
[DllImport("kernel32.dll")]
static extern bool Process32First(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
static extern bool Process32Next(IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
#endregion
同样重要的是 IWin32Window
的实现
// Implementation of IWin32Window
// ----------------------------------------
class WinWrapper : System.Windows.Forms.IWin32Window
{
public WinWrapper(IntPtr oHandle)
{
_oHwnd = oHandle;
}
public IntPtr Handle
{
get { return _oHwnd; }
}
private IntPtr _oHwnd;
}
全部使用
假设父进程是基于窗体的,而子进程是控制台应用程序。子进程需要显示一个对话框,它可以这样做
Process oParent = GetParentProcess();
WinWrapper oParentHandle = new WinWrapper(oParent.MainWindowHandle);
MessageBox.Show(oParentHandle, "Hello Child Parent proc world!");
关注点
有趣的是,窗口 IntPtr
句柄必须封装在 IWin32Window
中,它只是返回相同的内容。我尝试了 NativeWindow
类,但它没有帮助!
祝你好运,希望有人觉得这段代码有用,并感谢所有在 Code Project 上发布代码的人!
历史
- 2008年3月15日:初步发布