Reputation: 141638
I have a program that checks only one copy of itself is running: (C++ pseudocode)
int main()
{
HANDLE h_mutex = CreateMutex(NULL, TRUE, "MY_APP_NAME");
if ( !h_mutex )
{
ErrorMessage("System object already exists");
return EXIT_FAILURE;
}
else if ( GetLastError() == ERROR_ALREADY_EXISTS )
{
ErrorMessage("App is already running");
return EXIT_FAILURE;
}
// rest of code
ReleaseMutex(h_mutex);
CloseHandle(h_mutex);
return 0;
}
I would like to improve the error message "App is already running"
, and instead have it say "App is already running - started by USER at DATETIME, pid PID, OTHERINFO"
.
Is it possible for the first instance of my application to "register" a text string when creating the Mutex (or just after that); so that when another instance of my application detects that the Mutex already exists, it it can retrieve that text string and display that information?
Upvotes: 0
Views: 111
Reputation: 2184
You can do a lot of thing. You can store the text in a file and when your application opens, read it to check Mutex name. Or you can store it in Registry. Or you can send message to your application window. Still there is ways to do such a thing. You should decide which one is best fit for your application.
Upvotes: -1
Reputation: 1875
You could use CreateFileMapping
and MapViewOfFile
to share a structure between the existing process and the newly started process. You would need to create a named Event as well as the mutex that you already create to ensure that any information your store in the mapping is initialized before you try to read it in the new process.
The basic process would be:
Create the mutex as you do now.
If the mutex did not previously exist then you will use CreateFileMapping
to create a named mapping backed by the page file (you'll pass INVALID_HANDLE_VALUE as the file handle). Use MapViewOfFile
to map the section into the process address space. Initialize the contents of the shared memory with whatever information you want to share, remember that the address of the shared block will (likely) be different between processes, so don't use any pointers in the data. If you must, you offsets from the mapped address to make references (only within the shared section). Use CreateEvent
to create a named manual reset event, use SetEvent
to set the named event.
If the mutex existed previously, use CreateEvent
to create the named event mentioned in the previous paragraph. Use WaitForSingleObject
(or any other wait function) to wait for the named event to become signaled. This wait ensures that the original process has had a chance to initialize the contents of the shared section. Use CreateFileMapping
and MapViewOfFile
to map the shared section into the process address space and read whatever information you chose to store in the shared area.
Eventually, CloseHandle
everything and exit.
As a side note, you do not need to take ownership of the mutex when creating it. The mutex in this case is really just a named object that you can determine whether or not it existed before you tried to create it. You chould use a semaphore, event, or even the shared section from CreateFileMapping
.
Upvotes: 4