To prevent duplicate application instances from running I create a mutex using CreateMutexA
Win32 API call. However, this does not prevent duplicate processes as multiple mutexes with identical names are created. What am I doing wrong?
Code:
use windows::Win32::Foundation::{
GetLastError,
ERROR_ALREADY_EXISTS
};
use windows::Win32::System::Threading::{
CreateMutexA,
};
use windows::core::PCSTR;
pub fn prevent_duplicate() {
let mutex_key = static_key_as_string!();
log::info!("Mutex value: {mutex_key}");
log::info!("Creating Mutex");
unsafe {
match CreateMutexA(None, false, PCSTR(mutex_key.as_ptr() as *const u8)) {
Ok(_) => {
let error = GetLastError();
log::error!("{:?} {:?}", error, ERROR_ALREADY_EXISTS);
if error == ERROR_ALREADY_EXISTS {
log::info!("Mutex exists. Exiting");
std::process::exit(0)
}
},
Err(_) => {
log::error!("Could not check existence of Mutext. Continuing");
},
};
}
}
Output proc 1:
[INFO ] Mutex value: P889Z0Hhy2TKEPykDSLuSWdE9bJfNfCsK87aqgNGZ6b09NBIwBh6bwJBj98AkTzO
[INFO ] Creating Mutex
[ERROR] WIN32_ERROR(0) WIN32_ERROR(183)
Output proc 2:
[INFO ] Mutex value: P889Z0Hhy2TKEPykDSLuSWdE9bJfNfCsK87aqgNGZ6b09NBIwBh6bwJBj98AkTzO
[INFO ] Creating Mutex
[ERROR] WIN32_ERROR(0) WIN32_ERROR(183)
EDIT: setting bInitialOwner
to true
still allows for multiple instances
Check that the string is null-terminated. PCSTR
requires your string to have a 0 byte at the end; the default in Rust is that strings are not null-terminated.
You can include an explicit \0
at the end of the string, but it's probably best to use the windows::core::s!
macro, like this example.