我有一个程序只检查自身的一个副本正在运行:(C ++伪代码)
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;
}
我想改进错误消息"App is already running"
,而是让它说"App is already running - started by USER at DATETIME, pid PID, OTHERINFO"
。
我的应用程序的第一个实例是否有可能在创建Mutex时(或之后)“注册”文本字符串;这样当我的应用程序的另一个实例检测到Mutex已经存在时,它是否可以检索该文本字符串并显示该信息?
答案 0 :(得分:4)
您可以使用CreateFileMapping
和MapViewOfFile
在现有流程和新启动的流程之间共享结构。您需要创建一个命名事件以及您已创建的互斥锁,以确保在您尝试在新过程中读取它之前初始化映射中的商店的任何信息。
基本过程是:
像现在一样创建互斥锁。
如果以前不存在互斥锁,那么您将使用CreateFileMapping
创建由页面文件支持的命名映射(您将传递INVALID_HANDLE_VALUE作为文件句柄)。使用MapViewOfFile
将该部分映射到进程地址空间。使用您想要共享的任何信息初始化共享内存的内容,请记住共享块的地址(可能)在进程之间是不同的,因此不要在数据中使用任何指针。如果必须,则从映射地址偏移以进行引用(仅在共享部分内)。使用CreateEvent
创建命名手动重置事件,使用SetEvent
设置命名事件。
如果先前存在互斥锁,请使用CreateEvent
创建上一段中提到的命名事件。使用WaitForSingleObject
(或任何其他等待函数)等待命名事件发出信号。此等待可确保原始进程有机会初始化共享节的内容。使用CreateFileMapping
和MapViewOfFile
将共享部分映射到进程地址空间,并读取您选择存储在共享区域中的任何信息。
最终,CloseHandle
所有内容并退出。
作为旁注,您在创建互斥锁时无需拥有互斥锁。在这种情况下,互斥锁实际上只是一个命名对象,您可以在尝试创建它之前确定它是否存在。您可以使用信号量,事件,甚至是CreateFileMapping
的共享部分。
答案 1 :(得分:-1)
你可以做很多事情。您可以将文本存储在文件中,当应用程序打开时,请将其读取以检查互斥锁名称。或者您可以将其存储在注册表中。或者您可以将消息发送到您的应用程序窗口。还有办法做这样的事情。您应该决定哪一个最适合您的应用。