Click here to Skip to main content
16,015,583 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using Win32 API and have an application that controls a piece of hardware and initializes it upon the start. The hardware driver is acting up and once in a while the call to one of the SDK functions never returns... and the entire application just hangs up. The process is still visible in the list in Windows Task Manager, and it has to be manually ended before the application can be restarted.
I am looking for a way to do this from inside my program.
Thank you.

Reviewed version of the question:
How do I programmatically determine during the start of my application if another instance of it is already running on a system and, preferably, how do I terminate that process?
Posted
Updated 19-Mar-14 9:21am
v2
Comments
[no name] 18-Mar-14 21:24pm    
This is not a good approach and would never have been acceptable for any client I have worked for. Can't you improve your program to deal with this situation better.
SMD111 19-Mar-14 13:15pm    
It is not a good approach but the last resort. In my original post I indicated that the problem originates in the SDK that comes with the hardware device I am using. I have no control over that code. Instead, I have a very bad experience arguing with that company about undocumented behavior of their software in my previous projects.
[no name] 19-Mar-14 19:06pm    
This solution will be more fragile than your current solution. If you call the sdk from the main thread then you have no control but if you call from another thread with a timeout then you may be able to exit your program gracefully. This is what I was getting at.
SMD111 21-Mar-14 14:25pm    
Good idea, thank you. I coded it today and it works.
In case it helps somebody, I am putting a snapshot of the code in the "solutions" section.

1) Enumerating the processes:
C++
DWORD processes[1024], processes_size, i, n;
char buffer[256];
HANDLE ph;

memset(processes, 0, 1024 * sizeof(DWORD));

FILE* fp = fopen("results.txt", "w");
if(EnumProcesses(processes, sizeof(processes), &processes_size))
	for(i=0; i<processes_size; i++) {
		if(processes[i] == 0) continue;
		ph = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, processes[i]);
		n = GetModuleBaseNameA(ph, 0, buffer, sizeof(buffer));
		CloseHandle(ph);
		if(n==0) continue;
		fprintf(fp, "%d\t%d\t%s\n", i, n, buffer);
		}
fclose(fp);


2) Using a thread with timeout
C++
DAQ_Device* Device;


DWORD DevInitProc(LPBYTE lpData) {
DAQ_Device* Dev = (DAQ_Device*) lpData;
return Dev->HardwareInit();		// returns TRUE on success
}


// In the application main window process:
case WM_CREATE: {
	//.................
	Device = new DAQ_Device(hWnd);	// The constructor just allocates memory and zeroes the variables

	DWORD dwThreadID;
	HANDLE hSSIThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL, 0, (LPTHREAD_START_ROUTINE) DevInitProc, (LPVOID) Device, 0, &dwThreadID);
	if(hSSIThread == NULL) { ErrorReport(MODULE, __LINE__); return -1; }
	
	DWORD Status = WaitForSingleObject(hSSIThread, 500);
	switch (Status) {
		case WAIT_FAILED: { ErrorReport(MODULE, __LINE__); return -1; }
		case WAIT_OBJECT_0: {	// Normal thread termination
			DWORD dwExitCode;
			// What did DevInitProc() return?
			if(!GetExitCodeThread(hSSIThread, &dwExitCode)) { ErrorReport(MODULE, __LINE__); return -1; }
			if(!dwExitCode) {	// DevInitProc() returned FALSE
				MessageBox(hWnd, "Instrument not found.\nCheck the power switch.", " Attention:", MB_OK | MB_ICONEXCLAMATION);
				return -1;
				}
			if(!CloseHandle(hSSIThread)) { ErrorReport(MODULE, __LINE__); return -1; }
			break;	// DevInitProc returned TRUE, continue with WM_CREATE
			}
		case WAIT_TIMEOUT: {
			MessageBox(hWnd, "A hardware initialization problem detected.\nPlease call for instructions.", " Attention:", MB_OK | MB_ICONEXCLAMATION);
			TerminateThread(hSSIThread, 0);
			CloseHandle(hSSIThread);
			return -1;
			}
		}
	//.................
	break;
	}	// WM_CREATE
 
Share this answer
 
v2
 
Share this answer
 
Comments
SMD111 18-Mar-14 14:22pm    
Thanks, I do get a list of processes using calls to EnumProcesses(), OpenProcess() and GetModuleBaseName() functions.
However, using this method I get at least 50 processes named Ä, and then pairs like these:
75 notepad++.exe
76 Äotepad++.exe
77 firefox.exe
78 Äirefox.exe

Something is not working here.
SMD111 18-Mar-14 17:18pm    
One must check the return value of GetModuleBaseName() function because it often returned zero in my case. I also found that the technique described above only retrieves a list of 32-bit processes (the ones that appear as "name.exe *32" in the Task Manager).

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



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