TCHAR szCurPath[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH, szCurPath);
TCHAR szFile[MAX_PATH] = {0};
_stprintf_s(szFile, MAX_PATH, _T("%s\\setup.exe"), szCurPath);
CString szPath = szFile;
CString szCmdline = _T("");
CString szWorking;
szWorking = szPath.Mid( 0, szPath.ReverseFind( '\\' ) );
PROCESS_INFORMATION pi;
STARTUPINFO si;
memset( &si, 0, sizeof( si ) );
si.cb = sizeof( si );
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
szCmdline = _T("/NCRC /S /D=");
szCmdline.Append(szCurPath);
BOOL fRet = CreateProcess( szPath, szCmdline.GetBuffer(), NULL, FALSE, NULL, NULL, NULL, szWorking, &si, &pi );
...
以上方法使用CreateProcess函数创建一个进程并启动安装包静默安装,/D指定默认安装位置(没有引号,否则不生效),优先级最高。
不过当遇到需要提示权限的情况(需要以管理员身份运行),CreateProcess会执行失败,这时需提升权限,代码如下:
// ------提升权限------
// Initialize the structure.
SHELLEXECUTEINFO sei = { sizeof(SHELLEXECUTEINFO) };
sei.fMask = SEE_MASK_NOCLOSEPROCESS;
// Ask for privileges elevation.
sei.lpVerb = TEXT("runas");
// Create a Command Prompt from which you will be able to start
// other elevated applications.
sei.lpFile = szFile;
sei.lpParameters = szCmdline;
sei.lpDirectory = szWorking;
// Don't forget this parameter; otherwise, the window will be hidden.
sei.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&sei)) {
DWORD dwStatus = GetLastError();
if (dwStatus == ERROR_CANCELLED) {
// The user refused to allow privileges elevation.
UpdateMessage(_T("用户拒绝安装,升级失败。"));
}
else if (dwStatus == ERROR_FILE_NOT_FOUND) {
// The file defined by lpFile was not found and
// an error message popped up.
UpdateMessage(_T("升级包不存在,请检查!"));
}
CString strMsg;
::GetLastErrorString(strMsg);
LOG_ERROR(_T("启动安装程序失败:%s"), strMsg);
return -1;
}
m_hCreatePackage = sei.hProcess; // 句柄
m_hCreatePackage 存储安装包进程的句柄,有了它我们就可以使用 WaitForSingleObject 对其执行各阶段的逻辑进行处理,后面请大家自己发挥了。