MFC在对话框中设置后,点击按钮关闭软件后重启软件
1.今天在项目中遇到了一个问题:项目中要求在对话框中设置完成后,点击按钮后关闭整个软件程序,然后重启软件。而且软件设置了不允许多个软件打开(使用Mutex只允许打开一个软件)。一开始的做法如下:
// 向CMainFrame发送关闭窗口消息
AfxGetMainWnd()->SendMessage(WM_CLOSE,0,0);
// 打开当前运行的软件
TCHAR Current_location[MAX_PATH];//01
GetModuleFileName(NULL, Current_location, MAX_PATH);//02
ShellExecute(NULL, TEXT("OPEN"), Current_location, NULL, NULL, SW_SHOWNORMAL);//03
虽然可以关闭软件,但是后台依然会运行。会弹出一次只能运行一个软件的提示。
又进行了第二次尝试:
::PostMessage(AfxGetMainWnd()->m_hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL);
//获取exe程序当前路径
extern CDrawDxfFileApp theApp;
TCHAR szAppName[MAX_PATH];
:: GetModuleFileName(theApp.m_hInstance, szAppName, MAX_PATH);
CString strAppFullName;
strAppFullName.Format(_T("%s"),szAppName);
//重启程序
STARTUPINFO StartInfo;
PROCESS_INFORMATION procStruct;
memset(&StartInfo, 0, sizeof(STARTUPINFO));
StartInfo.cb = sizeof(STARTUPINFO);
::CreateProcess(
(LPCTSTR)strAppFullName,
NULL,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&StartInfo,
&procStruct);
但是依然不能实现,依然会弹出提示。如下显示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CdaM1vzb-1691768135984)(C:\Users\Administrator\Desktop\微信截图_20230811231336.png)]
一次只能运行一个软件的代码如下:
HANDLE hMutex = ::CreateMutex(NULL, FALSE, _T("{A2224701-B9F8-4AC4-BBD0-8B81D56B2E00}"));
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
AfxMessageBox(_T("已经有一个实例正在运行中……"));
CloseHandle(hMutex);
//虽然返回ERROR_ALREADY_EXISTS=183错误信息,但是互斥锁对象还是创建成功的,所以需要关闭
hMutex = NULL;
return FALSE;
}
代码要加在主线程的InitInstance函数中[APP的InitInstance函数中],注意代码要放在窗口显示之前:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KaNAmac-1691768135985)(C:\Users\Administrator\Desktop\微信截图_20230811231733.png)]
尝试第3种方式,代码如下:
extern CDrawDxfFileApp theApp;
TCHAR szAppName[MAX_PATH];
::GetModuleFileName(theApp.m_hInstance, szAppName, MAX_PATH);
CString strAppFullName;
strAppFullName.Format(_T("%s"), szAppName);
//重启程序
STARTUPINFO StartInfo;
PROCESS_INFORMATION procStruct;
memset(&StartInfo, 0, sizeof(STARTUPINFO));
StartInfo.cb = sizeof(STARTUPINFO);
// 最重要的环节,产生一个新的进程
::CreateProcess(
(LPCTSTR)strAppFullName,
NULL,
NULL,
NULL,
FALSE,
NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&StartInfo,
&procStruct);
// 终止原来的程序
::TerminateProcess(::GetCurrentProcess(),0);
说明:运行上面的代码,切实可行点击按钮关闭软件后,软件自动重启。
小结:
ShellExecute :对指定文件执行操作。
STARTUPINFO:指定创建时进程的主窗口的窗口工作站、桌面、标准句柄和外观。
PROCESS_INFORMATION:包含有关新创建的进程及其主线程的信息。 它与 CreateProcess、CreateProcessAsUser、CreateProcessWithLogonW 或 CreateProcessWithTokenW 函数一起使用。
CreateProcess:创建新进程及其主线程。 新进程在调用进程的安全上下文中运行。
TerminateProcess:终止指定的进程及其所有线程。
arn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess):终止指定的进程及其所有线程。
好了,今天就介绍到这里,欢迎大家一起学习交流。