How to find out if process created with ShellExecuteEx owns a window? - c++

I'm using ShellExecuteEx to run external application:
SHELLEXECUTEINFO shExInfo = { 0 };
shExInfo.cbSize = sizeof(shExInfo);
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExInfo.hwnd = 0;
shExInfo.lpVerb = L"runas"; // Operation to perform
shExInfo.lpFile = windowStringContainingAppPath.c_str(); // Application to start
shExInfo.lpParameters = windowStringContainingAppParameters.c_str(); // Additional parameters
shExInfo.lpDirectory = 0;
shExInfo.nShow = SW_SHOW;
shExInfo.hInstApp = 0;
if(ShellExecuteEx(&shExInfo))
{
WaitForSingleObject(shExInfo.hProcess, INFINITE);
DeleteFile(wsMesh3dx64Parameter.c_str());
CloseHandle(shExInfo.hProcess);
}
Everything works perfectly but there exist an unplanned behaviour of this external app that after closing its main window its process is still active.
This prevents WaitForSingleObject(shExInfo.hProcess, INFINITE); from returning and I have to terminate the process manualy.
Instead I'm looking for a way to replace WaitForSingleObject(shExInfo.hProcess, INFINITE);with a loop that checks if external process owns a window and if not terminate it.
This is what I thought of but if there is a better way please point it out for me.
UPDATE:
Thanks to Robson answer I managed to do what I intended to:
struct Porcess_ID_HWND
{
DWORD processID;
HWND processhWnd;
};
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
Porcess_ID_HWND*info = (Porcess_ID_HWND*)lParam;
DWORD processID;
GetWindowThreadProcessId(hWnd, &processID);
if (processID == info->processID){
info->processhWnd = hWnd;
return FALSE;
}
return TRUE;
}
And my loop:
if(ShellExecuteEx(&shExInfo))
{
DWORD dwProcessID = GetProcessId(shExInfo.hProcess);
Porcess_ID_HWND info;
info.processID = dwProcessID;
// wait for window to appear
do
{
info.processhWnd = NULL;
EnumWindows(EnumWindowsProc, (LPARAM)&info);
} while (!info.processhWnd);
// wait for window to close
do
{
info.processhWnd = NULL;
EnumWindows(EnumWindowsProc, (LPARAM)&info);
} while (info.processhWnd);
//WaitForSingleObject(shExInfo.hProcess, INFINITE);
DeleteFile(wsMesh3dx64Parameter.c_str());
CloseHandle(shExInfo.hProcess);
}

found a good answer at http://forums.codeguru.com/showthread.php?392273-RESOLVED-How-to-get-window-s-HWND-from-it-s-process-handle
1)
HAVE: Process ID, NEED: Process handle
Solution: OpenProcess()
2)
HAVE: Process handle, NEED: Process ID
Solution: GetProcessId()
3)
HAVE: Window handle, NEED: Process ID
Solution: GetWindowThreadProcessId()
4)
HAVE: Window handle, NEED: Process handle
Solution: Use 3) and then 1)
5)
HAVE: Process ID, NEED: Window handle
Solution: EnumWindows(), then in the callback function do 3) and check if it matches your process ID.
6)
HAVE: Process handle, NEED: Window handle
Solution: 2) and then 5)
so you are in case 6. then if no window handle's process ID is matched with your shExInfo.hProcess's process ID then shExInfo.hProcess owns no window

Related

Hot to get a window handle having the process id? [duplicate]

How to get main window handle from process id?
I want to bring this window to the front.
It works well in "Process Explorer".
I checked how .NET determines the main window.
My finding showed that it also uses EnumWindows().
This code should do it similarly to the .NET way:
struct handle_data {
unsigned long process_id;
HWND window_handle;
};
HWND find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
data.window_handle = 0;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.window_handle;
}
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle))
return TRUE;
data.window_handle = handle;
return FALSE;
}
BOOL is_main_window(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
I don't believe Windows (as opposed to .NET) provides a direct way to get that.
The only way I know of is to enumerate all the top level windows with EnumWindows() and then find what process each belongs to GetWindowThreadProcessID(). This sounds indirect and inefficient, but it's not as bad as you might expect -- in a typical case, you might have a dozen top level windows to walk through...
There's the possibility of a mis-understanding here. The WinForms framework in .Net automatically designates the first window created (e.g., Application.Run(new SomeForm())) as the MainWindow. The win32 API, however, doesn't recognize the idea of a "main window" per process. The message loop is entirely capable of handling as many "main" windows as system and process resources will let you create. So, your process doesn't have a "main window". The best you can do in the general case is use EnumWindows() to get all the non-child windows active on a given process and try to use some heuristics to figure out which one is the one you want. Luckily, most processes are only likely to have a single "main" window running most of the time, so you should get good results in most cases.
This is my solution using pure Win32/C++ based on the top answer. The idea is to wrap everything required into one function without the need for external callback functions or structures:
#include <utility>
HWND FindTopWindow(DWORD pid)
{
std::pair<HWND, DWORD> params = { 0, pid };
// Enumerate the windows using a lambda to process each window
BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
auto pParams = (std::pair<HWND, DWORD>*)(lParam);
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second)
{
// Stop enumerating
SetLastError(-1);
pParams->first = hwnd;
return FALSE;
}
// Continue enumerating
return TRUE;
}, (LPARAM)&params);
if (!bResult && GetLastError() == -1 && params.first)
{
return params.first;
}
return 0;
}
Though it may be unrelated to your question, take a look at GetGUIThreadInfo Function.
As an extension to Hiale's solution, you could provide a different or modified version that supports processes that have multiple main windows.
First, amend the structure to allow storing of multiple handles:
struct handle_data {
unsigned long process_id;
std::vector<HWND> handles;
};
Second, amend the callback function:
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle)) {
return TRUE;
}
// change these 2 lines to allow storing of handle and loop again
data.handles.push_back(handle);
return TRUE;
}
Finally, amend the returns on the main function:
std::vector<HWD> find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.handles;
}
Just to make sure you are not confusing the tid (thread id) and the pid (process id):
DWORD pid;
DWORD tid = GetWindowThreadProcessId( this->m_hWnd, &pid);

C++/Win32 enumerate windows belonging to my process & close them

I have a Windows app that houses a web browser (Internet explorer) embedded in it. The app can be closed from another process by means of IPC. It works just fine except the situation when the embedded web browser may be displaying a pop-up dialog window (say, during saving of contents). In that case my app crashes when it tries to close from an outside request via IPC. (Internally it simply posts the WM_CLOSE message to itself.)
In light of that I thought to come up with a way to enumerate all windows that belong to my process and close them first before closing my process itself. The question is, how do you enumerate all windows belonging to my process for the purpose of closing them?
OK, I guess I got it myself. Here's if someone is interested:
#define SIZEOF(f) (sizeof(f) / sizeof(f[0]))
typedef struct _ENUM_POPUPS_INFO{
DWORD dwProcID;
HWND hThisWnd;
int nNextHWNDIndex;
HWND hFoundHWNDs[256];
}ENUM_POPUPS_INFO;
void CloseAllOpenPopups(HWND hWnd, int dwmsWait)
{
//'hWnd' = our main window handle (we won't close it)
//'dwmsWait' = maximum wait time in milliseconds, or -1 to wait for as long as needed
ENUM_POPUPS_INFO epi = {0};
BOOL bR;
int i, iIteration;
HWND hWndRoot, hWndActivePopup;
DWORD dwmsTickBegin = GetTickCount();
for(iIteration = 0;; iIteration = 1)
{
//Get our process ID
memset(&epi, 0, sizeof(epi));
epi.hThisWnd = hWnd;
epi.dwProcID = GetCurrentProcessId();
bR = EnumWindows(EnumPopupWindowsProc, (LPARAM)&epi);
//Did we get any
if(epi.nNextHWNDIndex == 0)
break;
//Wait on a second and later iteration
if(iIteration > 0)
{
if(dwmsWait != -1)
{
DWORD dwmsTick = GetTickCount();
int nmsDiff = abs((long)(dwmsTick - dwmsTickBegin));
if(nmsDiff >= dwmsWait)
{
//Timed out
break;
}
//Wait
Sleep(min(100, dwmsWait - nmsDiff));
}
else
{
//Wait
Sleep(100);
}
}
//Go through all windows found
for(i = 0; i < epi.nNextHWNDIndex; i++)
{
//Get root owner
hWndRoot = GetAncestor(epi.hFoundHWNDs[i], GA_ROOTOWNER);
if(!hWndRoot)
continue;
//Get it's active popup
hWndActivePopup = GetLastActivePopup(hWndRoot);
if(!hWndActivePopup)
continue;
//Close it
PostMessage(hWndActivePopup, WM_CLOSE, 0, 0);
}
}
}
BOOL CALLBACK EnumPopupWindowsProc(HWND hWnd, LPARAM lParam)
{
ENUM_POPUPS_INFO* pEPI = (ENUM_POPUPS_INFO*)lParam;
//Get process ID of the window
DWORD dwProcID = 0;
GetWindowThreadProcessId(hWnd, &dwProcID);
//We need this window only if it's our process
if(dwProcID == pEPI->dwProcID &&
pEPI->hThisWnd != hWnd &&
((GetWindowLongPtr(hWnd, GWL_STYLE) & (WS_VISIBLE | WS_POPUP | WS_CAPTION)) == (WS_VISIBLE | WS_POPUP | WS_CAPTION)))
{
if(pEPI->nNextHWNDIndex >= SIZEOF(pEPI->hFoundHWNDs))
{
//Stop, we're full
return FALSE;
}
//Add it
pEPI->hFoundHWNDs[pEPI->nNextHWNDIndex] = hWnd;
pEPI->nNextHWNDIndex++;
}
return TRUE;
}
When you want your process to exit, just call ExitProcess. It doesn't matter what windows might be open at the time, they all go away.

How to Run Only One Instance of Application

I have a application which uses socket connection to send and receive data from another application. While creating socket it uses the port 4998 .
That is where my problem lie. Once I start my application the socket starts using port 4998. So if I want to execute the application again then I get socket binding error.
So I want to limit my application instance to one. That means if the application is already running and some one tries to run the application again by clicking the exe or shortcut icon it shouldn't run the program, instead it should bring the existing application to the Top.
You may used named mutex.
Code sample from the article:
WINAPI WinMain(
HINSTANCE, HINSTANCE, LPSTR, int)
{
try {
// Try to open the mutex.
HANDLE hMutex = OpenMutex(
MUTEX_ALL_ACCESS, 0, "MyApp1.0");
if (!hMutex)
// Mutex doesn’t exist. This is
// the first instance so create
// the mutex.
hMutex =
CreateMutex(0, 0, "MyApp1.0");
else
// The mutex exists so this is the
// the second instance so return.
return 0;
Application->Initialize();
Application->CreateForm(
__classid(TForm1), &Form1);
Application->Run();
// The app is closing so release
// the mutex.
ReleaseMutex(hMutex);
}
catch (Exception &exception) {
Application->
ShowException(&exception);
}
return 0;
}
When your application initializes, create a mutex. If it already exists, find the existing application and bring it to the foreground. If the application has a fixed title for its main window, it is easy to find with FindWindow.
m_singleInstanceMutex = CreateMutex(NULL, TRUE, L"Some unique string for your app");
if (m_singleInstanceMutex == NULL || GetLastError() == ERROR_ALREADY_EXISTS) {
HWND existingApp = FindWindow(0, L"Your app's window title");
if (existingApp) SetForegroundWindow(existingApp);
return FALSE; // Exit the app. For MFC, return false from InitInstance.
}
/*
I have found the necessary editing to be done. Added some extra code and edits that are needed. The present one is working perfectly for me. Thank you, Kirill V. Lyadvinsky and Remy Lebeau for the help!!
*/
bool CheckOneInstance()
{
HANDLE m_hStartEvent = CreateEventW( NULL, FALSE, FALSE, L"Global\\CSAPP" );
if(m_hStartEvent == NULL)
{
CloseHandle( m_hStartEvent );
return false;
}
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
CloseHandle( m_hStartEvent );
m_hStartEvent = NULL;
// already exist
// send message from here to existing copy of the application
return false;
}
// the only instance, start in a usual way
return true;
}
/*
The above code works even when one tries to open up second instance FROM A DIFFERENT LOGIN LEAVING THE FIRST LOGIN OPEN with ITS INSTANCE RUNNING.
*/
Create named event on the start and check the result. Close application if the event is already exist.
BOOL CheckOneInstance()
{
m_hStartEvent = CreateEventW( NULL, TRUE, FALSE, L"EVENT_NAME_HERE" );
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
CloseHandle( m_hStartEvent );
m_hStartEvent = NULL;
// already exist
// send message from here to existing copy of the application
return FALSE;
}
// the only instance, start in a usual way
return TRUE;
}
Close m_hStartEvent on the app exit.
You can achieve this in your WindowMain function by calling the FindWindow function with the class name and the title of your main window at the very beginning. If the window exists you can either show a message to the user or simply show the window and then return:
HWND hWnd = FindWindow(lzClassName, lzWindowText);
if(hWnd!=NULL)
{
ShowWindow(hWnd, SW_SHOW);
return 0;
}
WNDCLASSEX wcex;
/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
...
Don't you already have a way to check if your application is running? Who needs a Mutex, if the port is already taken, you know that the app is running!

How to get handles to all windows of another application

in my application i have timer, in TimerProc i want to get handles of all windows(main and child) of the another application that has focus. I have no idea how to do that because i don't understand functions like GetNextWindow or GetParent and Z-oder of windows and i can't find anywhere very detailed explanation of how this functions works(i dont understand explanation on msdn). Please can you give me some advice or block of code which do that? Many thanks for answer.
Use GetForegroundWindow() function - it returns the HWND of the window the user currently is working with.
Then having this handle you can retrieve childs in such a way:
HWND a_hWnd = (HWND)hParent;
HWND a_FirstChild = NULL;
a_FirstChild = ::GetWindow(a_hWnd, GW_CHILD);
if (a_FirstChild != NULL)
{
HWND a_NextChild = NULL;
do
{
a_NextChild = ::GetWindow(a_FirstChild, GW_HWNDNEXT);
if (a_NextChild != NULL)
{
a_FirstChild = a_NextChild;
}
}
while (a_NextChild != NULL);
}
GetForeGroundWindow to get the current foreground window/dialog
GetParent until you get NULL (that gets you to the top level window)**
EnumChildWindows to get to all the dependent windows
** Note that an application can have more than one top level window, though this isn't usual.
Code:
void Ccpp_testDlg::DoWalk ()
{
HWND hCurrent;
HWND hNew;
hCurrent = ::GetForegroundWindow ();
hNew = hCurrent;
while (hNew != NULL)
{
hNew = ::GetParent (hCurrent);
if (hNew != NULL)
{
hCurrent = hNew;
}
}
EnumChildWindows (hCurrent, EnumProc, 0);
}
BOOL CALLBACK EnumProc (HWND hwnd,LPARAM lParam)
{
TCHAR szText [MAX_PATH];
GetWindowText (hwnd, szText, sizeof(szText));
// do something with text
return TRUE;
}

How to get main window handle from process id?

How to get main window handle from process id?
I want to bring this window to the front.
It works well in "Process Explorer".
I checked how .NET determines the main window.
My finding showed that it also uses EnumWindows().
This code should do it similarly to the .NET way:
struct handle_data {
unsigned long process_id;
HWND window_handle;
};
HWND find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
data.window_handle = 0;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.window_handle;
}
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle))
return TRUE;
data.window_handle = handle;
return FALSE;
}
BOOL is_main_window(HWND handle)
{
return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle);
}
I don't believe Windows (as opposed to .NET) provides a direct way to get that.
The only way I know of is to enumerate all the top level windows with EnumWindows() and then find what process each belongs to GetWindowThreadProcessID(). This sounds indirect and inefficient, but it's not as bad as you might expect -- in a typical case, you might have a dozen top level windows to walk through...
There's the possibility of a mis-understanding here. The WinForms framework in .Net automatically designates the first window created (e.g., Application.Run(new SomeForm())) as the MainWindow. The win32 API, however, doesn't recognize the idea of a "main window" per process. The message loop is entirely capable of handling as many "main" windows as system and process resources will let you create. So, your process doesn't have a "main window". The best you can do in the general case is use EnumWindows() to get all the non-child windows active on a given process and try to use some heuristics to figure out which one is the one you want. Luckily, most processes are only likely to have a single "main" window running most of the time, so you should get good results in most cases.
This is my solution using pure Win32/C++ based on the top answer. The idea is to wrap everything required into one function without the need for external callback functions or structures:
#include <utility>
HWND FindTopWindow(DWORD pid)
{
std::pair<HWND, DWORD> params = { 0, pid };
// Enumerate the windows using a lambda to process each window
BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
{
auto pParams = (std::pair<HWND, DWORD>*)(lParam);
DWORD processId;
if (GetWindowThreadProcessId(hwnd, &processId) && processId == pParams->second)
{
// Stop enumerating
SetLastError(-1);
pParams->first = hwnd;
return FALSE;
}
// Continue enumerating
return TRUE;
}, (LPARAM)&params);
if (!bResult && GetLastError() == -1 && params.first)
{
return params.first;
}
return 0;
}
Though it may be unrelated to your question, take a look at GetGUIThreadInfo Function.
As an extension to Hiale's solution, you could provide a different or modified version that supports processes that have multiple main windows.
First, amend the structure to allow storing of multiple handles:
struct handle_data {
unsigned long process_id;
std::vector<HWND> handles;
};
Second, amend the callback function:
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
handle_data& data = *(handle_data*)lParam;
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id || !is_main_window(handle)) {
return TRUE;
}
// change these 2 lines to allow storing of handle and loop again
data.handles.push_back(handle);
return TRUE;
}
Finally, amend the returns on the main function:
std::vector<HWD> find_main_window(unsigned long process_id)
{
handle_data data;
data.process_id = process_id;
EnumWindows(enum_windows_callback, (LPARAM)&data);
return data.handles;
}
Just to make sure you are not confusing the tid (thread id) and the pid (process id):
DWORD pid;
DWORD tid = GetWindowThreadProcessId( this->m_hWnd, &pid);