Click here to Skip to main content
15,883,883 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
hi i run another program from inside my program by using CreateProcess function. it works properly, but i like to go further:
1. i want no separate task bar icon appear for the child program.
2. the program in executed by clicking on a toolbar icon in my program. i want if it clicked again, the child program gets activated instead of being executed again. now two separate child programs appear.
how can i?
thx
Posted
Updated 6-Oct-14 1:36am
v2
Comments
[no name] 2-Oct-14 6:59am    
What programming language is "Windows"? Create a mutex, if the "Windows" programming language supports that.
ilostmyid2 2-Oct-14 7:16am    
sorry, it's in C++. i've no control over the child application. i've no access to its source. it's not my program.
Richard MacCutchan 2-Oct-14 10:08am    
1. I don't think you can do that.
2. After clicking the "activate child" button, disable it so it cannot be called again, or keep a flag somewhere to prevent it being activated a second time.
ilostmyid2 2-Oct-14 10:11am    
2. good idea, but i can't find out when the child program is closed so that i may enable it again.
Richard MacCutchan 2-Oct-14 10:16am    
Don't you get a pointer or something from CreateProcess that you can use to find out when it closes?

CreateProcess fills properly the out parameter lpProcessInformation, that is a pointer to a PROCESS_INFORMATION[^] struct, defined this way:
C
typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;
  HANDLE hThread;
  DWORD  dwProcessId;
  DWORD  dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;


Passing the hProcess member of this struct to GetExitCodeProcess[^] you obtain the info you are searching for (e.g. STILL_ACTIVE if the child process is still running).

Read carefully the documentation.
 
Share this answer
 
Comments
ilostmyid2 6-Oct-14 9:45am    
then i should end the process? this way, i need to first execute the program and then figure out that it has been running. what i want is to prevent it to be executed again. there should be an IN parameter for this purpose, like a flag to specify it should be run as single-instance.
CPallini 6-Oct-14 9:48am    
"then i should end the process?"
Nope, on button click you have just to verify if there is already a child process running. If it is the case then you don't start a new child instance.
ilostmyid2 6-Oct-14 11:02am    
this is true only if my process has created the child process. if the process has been running before my process, or after my process but has been brought up by a user, then i can't check it.
CPallini 6-Oct-14 11:13am    
Yes, that's true. If you are indeed in such more complex scenarios then your life is more troubled and possibly the EnumWindows function is on your way.
thanks
based on your cooperation and my investigations the following code was resulted. i would expect such an answer.
good luck! :)
C++
struct handle_data
{
	unsigned long process_id;
	HWND best_handle;
};

BOOL is_main_window(HWND handle)
{   
	return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(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.best_handle = handle;
	return FALSE;   
}

HWND find_main_window(unsigned long process_id)
{
	handle_data data;
	data.process_id = process_id;
	data.best_handle = 0;
	EnumWindows(enum_windows_callback, (LPARAM)&data);
	return data.best_handle;
}

CString file_name(LPCSTR path)
{
	int len = strlen(path);
	for (int i = len - 1; i >= 0; i--)
		if (path[i] == '\\')
			return path + i + 1;
	return "";
}

// check whether the program is running. if so, it also brings it to front.
// prog may be something like "devenv.exe".
bool is_running(LPCSTR prog)
{
	void *buf = NULL;
	int estimatedRequiredBufSize = 300;
	DWORD requiredBufSize;
	while (true)
	{
		buf = realloc(buf, estimatedRequiredBufSize);
		VERIFY(EnumProcesses((DWORD *) buf, estimatedRequiredBufSize, &requiredBufSize));
		if (estimatedRequiredBufSize == requiredBufSize)
			estimatedRequiredBufSize *= 2;
		else
			break;
	}
	DWORD *pProcessIds = (DWORD *) buf;
	int numProcesses = requiredBufSize / sizeof(DWORD);
	for (int i=0; i<numprocesses;>	{
		HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pProcessIds[i]);
		if (hProcess)
		{
			char path[_MAX_PATH];
			DWORD size = sizeof(path) - 1, wholeSize = size;
			VERIFY(QueryFullProcessImageName(hProcess, 0, path, &size));
			ASSERT(size < wholeSize);
			if (file_name(path) == prog)
			{
				HWND hWnd = find_main_window(pProcessIds[i]);
				VERIFY(SetForegroundWindow(hWnd));
				free(pProcessIds);
				return true;
			}
		}
	}
	free(pProcessIds);
	return false;
}
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900