|
|||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article shows how to display a modal dialog/form against a parent processes window. The download file contains a demo solution that shows how to use all of the code shown here. BackgroundThis does not happen very often, but I recently needed to create a Windows service that needed to display a dialog window to collect some user information during the installation. During the development of the installation project, I started thinking how to make sure that the data collection form is not hidden and that the installation does not continue without the user completing the necessary details. I remember doing something like that in the past using MFC and WIN32, but I needed this for a .NET based solution. I decided to do some research. In CodeProject resources, I found a solution that shows how to get the parent process using WIN32, and I also found a way of wrapping the Here is the function that will retrieve the parent process: 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;
}
Here are the PInvoke definitions: #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
What is also important is the implementation of // Implementation of IWin32Window
// ----------------------------------------
class WinWrapper : System.Windows.Forms.IWin32Window
{
public WinWrapper(IntPtr oHandle)
{
_oHwnd = oHandle;
}
public IntPtr Handle
{
get { return _oHwnd; }
}
private IntPtr _oHwnd;
}
Using It AllAssume that the parent process is form based and the child process is a console application. The child process needs to display a dialog box and it can do so like this: Process oParent = GetParentProcess();
WinWrapper oParentHandle = new WinWrapper(oParent.MainWindowHandle);
MessageBox.Show(oParentHandle, "Hello Child Parent proc world!");
Points of InterestIt is interesting to see that the window Good luck, hope that someone finds this code useful, and thanks to all the people who have put their code on The Code Project! History
|
||||||||||||||||||||||||||||||||||||||||