Ответ 1
Используйте ShellExecuteEx
, а не ShellExecute
. Эта функция предоставит дескриптор созданного процесса, который вы можете использовать для вызова WaitForSingleObject
на этом дескрипторе, чтобы до тех пор, пока этот процесс не завершится. Наконец, просто вызовите CloseHandle
в дескрипторе процесса, чтобы закрыть его.
Пример кода (большая часть проверки ошибок опущена для ясности и краткости):
SHELLEXECUTEINFO shExInfo = {0};
shExInfo.cbSize = sizeof(shExInfo);
shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
shExInfo.hwnd = 0;
shExInfo.lpVerb = _T("runas"); // Operation to perform
shExInfo.lpFile = _T("C:\\MyApp.exe"); // Application to start
shExInfo.lpParameters = ""; // Additional parameters
shExInfo.lpDirectory = 0;
shExInfo.nShow = SW_SHOW;
shExInfo.hInstApp = 0;
if (ShellExecuteEx(&shExInfo))
{
WaitForSingleObject(shExInfo.hProcess, INFINITE);
CloseHandle(shExInfo.hProcess);
}
Определение глагола "runas" для lpVerb
- это то, что заставляет UAC поднимать приложение, которое должно быть запущено. Это эквивалентно настройке уровня разрешений в манифесте приложения на "requireAdministrator". Это потребует повышения UAC как для администратора, так и для ограниченного пользователя.
Но стоит отметить, что, если это абсолютно необходимо, вы должны предпочесть "стандартный" способ добавления манифеста в приложение, которое вы хотите запустить, которое определяет требуемый уровень выполнения. Если вы пройдете этот маршрут, вы просто передадите "open" в качестве lpVerb
. Пример манифеста показан ниже:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Наконец, убедитесь, что любой элемент в приложении запускает процесс, требующий повышения UAC, помечен соответствующим образом. Это ваша работа, чтобы моделировать это в пользовательском интерфейсе; Windows не обрабатывает его для вас. Это делается путем отображения значка экрана в точке входа; например:
< t40