Multiple program instance prevention in C

Hello Everyone,
I am working on eliminating program instability from existing programs we have developed at work. However, due to some of the constraints involved, we are forced to work in C, and not C++. For instance, we have a program designed to provide a GUI to control various parameters when a device is plugged in via USB. The program works, detecting when the device is plugged in, and allows parameters to be changed using sliders within the GUI. However, upon running multiple simultaneous iterations of the program, any subsequent executions beyond the first hang, and it fails to detect the USB device. Similarly, when running one instance of the program and the USB device is not connected, the program hangs. While I'm sure most problems stem from the USB interface and constantly ensuring it remains present, I'd like if someone could show me a simple way to prevent multiple instances of the program in C.

It is possible that this is the wrong forum, or that the topic would be more suited to another forum focusing on C altogether, but I figured I would start here.
Last edited on
Create a mutex.

If the mutex already exists, the program is already active. Send a signal to the mutex owner to focus itself, and terminate.

Otherwise, verify that the USB port is open. If it is open and ready, good to go. Else release the mutex and terminate.

Hope this helps.
Thanks Duoas,
In researching the topic, I had encountered the use of mutexes, and attempted to incorporate it into the program. However, C is a bit more unforgiving on syntax (or I've simply gravitated towards more intuitive methods included in C++). I tried it this way:
1
2
3
4
5
6
7
   const char szUniqueNamedMutex[] = "com_mycompany_apps_appname";
   HANDLE hHandle = CreateMutex( NULL, TRUE, szUniqueNamedMutex );
   if( ERROR_ALREADY_EXISTS == GetLastError() )
   {
      // Program already running somewhere
      return(1); // Exit program
   }

But it did not prevent the program from opening multiple instances. I also tried another method which searches the active windows for the program to determine the program's state, but had no luck with it either.
1
2
3
4
5
6
7
8
9
HWND hWnd=::FindWindow(LPCTSTR lpClassName, // pointer to class name
                       LPCTSTR lpWindowName // pointer to window name
                       );
if(hWnd != NULL)
{
   ShowWindow(hWnd,SW_NORMAL);
   // exit this instance
   return(1);
}

Apparently C does not take kindly to the use of ::, though. I need to explore the first option further, as apparently I did not properly set up the mutex by releasing and closing it later in the application. I wanted to avoid mucking up the existing program by introducing as few modifications as possible, but apparently there's no way around the need to modify some code.

Upon further discussion, the issue is complicated by the fact that when a single instance of the program is running, and a connection is not present, they do not want the program to terminate, but rather to await device connection. Preventing multiple instances of execution would solve our dilemma, but having instances of the program that do not find a connection terminate would result in a single instance of the program terminating when a connection isn't present as well.

If I understand correctly, I should be able to set up my Mutex at the beginning of the main function, and release and close it toward the end, perhaps something like this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main (int argc, char *argv[])
	{
	const char szUniqueNamedMutex[]="com_mycompany_apps_appname" ;
	HANDLE hHandle = CreateMutex( NULL, TRUE, szUniqueNamedMutex );
	if ( ERROR_ALREADY_EXISTS == GetLastError() )
	{
	return(1);
	}
	int i ;
	double x ;
	char buf[80] ;
	char filename[1024] ;
	int retval ;

	if (InitCVIRTE (0, argv, 0) == 0) return -1;	/* out of memory */ 
	if ((panelmain = LoadPanel (0, "main.uir", PANELMAIN)) < 0) return -1;

	GetDevices();
	DisplayPanel (panelmain);
	retval = RestoreSettings("settings.cfg") ;
	if(retval>0) 
		{
		sprintf(buf,"Unable to Restore All Settings.  %d of %d Restored",NUM_PARAMS_TO_SAVE-retval, 

NUM_PARAMS_TO_SAVE) ;
		MessagePopup("Restore Error", buf);
		}
	if(retval<0) MessagePopup ("Restore Error", "Unable to find Restore File");
	RunUserInterface ();
	DiscardPanel (panelmain);
	ReleaseMutex( hHandle );
	CloseHandle ( hHandle );
	return 0;
	}

I thought I had it with lines 3-7 and 31-32, but it didn't do the job. The program still allows multiple instances to open. I must be missing something fundamental. Could you provide me with a simple example of mutex creation, and checking for whether a program is active? It does not need to include the above code, and any example should suffice.
Last edited on
It is working for me:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
#include "windows.h"

int main() {
    const char szUniqueNamedMutex[] = "com_mycompany_apps_appname";
   HANDLE hHandle = CreateMutex( NULL, TRUE, szUniqueNamedMutex );
   if( ERROR_ALREADY_EXISTS == GetLastError() )
   {
      // Program already running somewhere
      std::cout << "Program already running, Press Enter to exit" << std::endl;
std::cin.ignore();
CloseHandle (hHandle);
      return(1); // Exit program
   }

    std::cout << "Press Enter to exit" << std::endl;
std::cin.ignore();
ReleseMutex (hHandle);
CloseHandle (hHandle);
return 0;
}



Please replace <iostream> calls with printf() or something like that if you must use C, I did not read carefully.
Last edited on
Once you gain the mutex, you must watch the USB port.

To watch the USB port, you'll have to register your window to receive device notifications.

Basic code here:
http://www.google.com/search?btnI=1&q=msdn+GetStdHandle

Good luck!
Thanks, both of you. I'll be exploring this further today. Based on your above example, modoran, I'm going to try this out to begin with.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
int main (int argc, char *argv[])
	{
	int i ;
	double x ;
	char buf[80] ;
	char filename[1024] ;
	int retval ;	
		
	const char szUniqueNamedMutex[]="com_mycompany_apps_appname" ;
	HANDLE hHandle = CreateMutex( NULL, TRUE, szUniqueNamedMutex );
	if ( ERROR_ALREADY_EXISTS == GetLastError() )
	{
	printf("Program Already Running...\n");
	CloseHandle ( hHandle );
	return(1);
	}

	if (InitCVIRTE (0, argv, 0) == 0) return -1;	/* out of memory */ 
	if ((panelmain = LoadPanel (0, "main.uir", PANELMAIN)) < 0) return -1;

	GetDevices();
	DisplayPanel (panelmain);
	retval = RestoreSettings("settings.cfg") ;
	if(retval>0) 
		{
		sprintf(buf,"Unable to Restore All Settings.  %d of %d Restored",NUM_PARAMS_TO_SAVE-retval, 

NUM_PARAMS_TO_SAVE) ;
		MessagePopup("Restore Error", buf);
		}
	if(retval<0) MessagePopup ("Restore Error", "Unable to find Restore File");
	RunUserInterface ();
	DiscardPanel (panelmain);
	ReleaseMutex( hHandle );
	CloseHandle ( hHandle );
	return 0;
	}
Last edited on
I tried the above code, with the USB device connected. Still, the first execution of the program detects the device and works correctly, but subsequent simultaneous executions still are allowed, and always fail to detect the device.

EDIT- The issue was compiler specific. Upon further experimentation, this is now working and prevents multiple program executions. Thanks to everyone for getting me on the right track.
Last edited on
Topic archived. No new replies allowed.