Ответ 1
Вы почти наверняка используете эвристику совместимости с Windows Installer Detection Technology. Windows попытается определить, когда приложение является установщиком, и, вероятно, необходимо повысить его.
Обнаружение установщика применяется только к:
- 32-разрядные исполняемые файлы
- Приложения без
requestedExecutionLevel
- Интерактивные процессы, выполняемые в качестве стандартного пользователя с включенным LUA
Перед созданием 32-битного процесса проверяются следующие атрибуты, чтобы определить, является ли он установщиком:
- Имя файла включает такие ключевые слова, как "установка", "настройка", "обновление" и т.д.
- Ключевые слова в следующих полях Ресурсы для Версии: поставщик, название компании, название продукта, описание файла, исходное имя файла, внутреннее имя и имя экспорта.
- Ключевые слова в бок о бок манифест, встроенный в исполняемый файл.
- Ключевые слова в определенных строковых записях, связанных в исполняемом файле.
- Ключевые атрибуты в данных RC, связанных с исполняемым файлом.
- Целевые последовательности байтов в исполняемом файле.
Итак, как вы сказали:
но у меня есть exe, который проверяет наличие обновлений для программного обеспечения
Я предполагаю, что этот CheckForUpdates.exe
запускает эвристику совместимости.
правильная вещь - это манифест сборки для вашего "проверяющего" исполняемого файла, информирующий Windows о том, что он должен не поднять утилиту. Это делается с помощью requestedExecutionLevel
asInvoker
в манифесте:
AssemblyManifest.xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="client"
type="win32"
/>
<description>Update checker</description>
<!-- Run as standard user. Disable file and registry virtualization -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Таким образом, приложение "Проверить на обновления" никогда не будет повышаться и никогда не будет ошибочно получать административные привилегии.
Если вы хотите, чтобы ваш обновитель действительно применял обновления (обновления, требующие административных привилегий), вы запустили приложение для обновления в качестве администратора.
Пример кода
//Check if there are updates available
if (!CheckForUpdatesAvailable())
return; //no updates. We're done
//If the user is an administrator, then get the update
if (IsUserAnAdmin())
{
//Maybe throw in a "Hey, user, wanna get the update now?" dialog
DownloadAndApplyUpdates();
return;
}
//The user is not an admin.
//Relaunch ourselves as administrator so we can download the update
//Maybe throw in a "Hey, user, wanna get the update now?" dialog. A button with a UAC shield on it
ExecuteAsAdmin(Application.ExecutablePath, "/downloadUpdate");
со вспомогательными функциями:
private Boolean IsUserAnAdmin()
{
//A user can be a member of the Administrator group, but not an administrator.
//Conversely, the user can be an administrator and not a member of the administrators group.
var identity = WindowsIdentity.GetCurrent();
return (null != identity && new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator));
}
private void ExecuteAsAdmin(string Filename, string Arguments)
{
ProcessStartInfo startInfo = new ProcessStartInfo(Filename, Arguments);
startInfo.Verb = "runas";
System.Diagnostics.Process.Start(startInfo);
}
Тогда вам просто нужно искать параметр командной строки /downloadUpdate при запуске, чтобы знать, что вы работаете, чтобы на самом деле работать:
public Form1()
{
InitializeComponent();
//Ideally this would be in program.cs, before the call to Application.Run()
//But that would require me to refactor code out of the Form file, which is overkill for a demo
if (FindCmdLineSwitch("downloadUpdate", true))
{
DownloadAndApplyUpdates();
Environment.Exit(0);
}
}
Примечание. Любой код выпущен в общедоступном домене. Не требуется атрибуция.