#c#
Вопрос:
Приношу извинения за длинный пост. Мой вопрос в том, каков наилучший метод, позволяющий моим пользователям назначать ассоциации файлов моему приложению. Я включил, куда я дошел до сих пор, но я совсем не уверен, что смотрю на это правильно.
Мое приложение использует определенное расширение (.ad2). Он запускается пользователями, использующими XP, Vista и Win7. Мне нужно поддержать их всех. В Vista и Win 7 для этого, конечно, требуются права администратора. Расположение моего исполняемого файла может отличаться в зависимости от того, где пользователь его установил. Я думаю, что хорошим методом было бы назначить ассоциацию при установке. Проблемы здесь в том, что некоторым моим пользователям не нравятся автоматические установщики, а также уже есть большая установленная база. Так что на данный момент я это устранил.
Я хочу, чтобы мои пользователи могли контролировать, связываются они или нет, поэтому процесс должен быть им виден
Следующее, о чем я подумал, — это встроить некоторый код в приложение, доступ к которому осуществляется через меню. Это прекрасно работает, так как приложение знает, где оно установлено. Однако он должен запускаться от имени администратора (я понимаю, что повышенные привилегии распространяются на весь процесс). Однако пользователю необходимо повысить разрешения перед запуском, чтобы обойти UAC.
Моя последняя мысль заключалась в том, чтобы перейти к новому процессу из пункта меню главного приложения, повысить разрешения для этого процесса и разрешить ему выполнять ассоциацию файлов. Исполняемый файл с оболочкой будет находиться в той же папке, что и мое основное приложение, поэтому он будет знать, где находятся такие вещи, как основной исполняемый файл и значок.
Я предпочитаю посвятить себя новому процессу — я прав?
Спасибо
Комментарии:
1. вы знаете о сопоставлениях пользователей, которым не нужны повышенные права для настройки?
2. поищи это в Интернете. Это кажется намного лучше, чем повышение вне времени установки
3. ХОРОШО — спасибо, я посмотрю
Ответ №1:
Решение, предложенное ScruffyDuck, использует отечественный подход к UAC, который является нестандартным и менее функциональным, чем стандартные средства, встроенные в Windows и которые, как ожидается, будут использовать разработчики.
Приложения, требующие прав администратора, должны быть помечены как таковые с помощью манифеста:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Примечание: это не полный манифест, я удалил все, кроме requestedExecutionLevel
настроек.
Это означает, что приложение будет отображать диалоговое окно повышения уровня контроля учетных записей при запуске.
Наконец, ничто из этого не помогает пользователям, не являющимся администраторами. По этой причине я бы выбрал ассоциации файлов для каждого пользователя.
Ответ №2:
Я отвечаю на это своими выводами, потому что это может быть полезно другим. Я не претендую на оригинальность этого, так как весь код исходит от других. Я решил создать отдельный исполняемый файл для запуска параметра ассоциации файлов. Я вызвал эту программу из пункта меню таким образом:
var proc = new ProcessStartInfo {
UseShellExecute = true,
WorkingDirectory = Environment.CurrentDirectory,
FileName = Path.Combine(Application.StartupPath, "ADEFileAssociator.exe"),
Verb = "runas"
};
try {
Process.Start(proc);
}
catch {
MessageBox.Show("Failed to start File Associator","Process Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
return;
}
Этот подход был описан в ответе здесь на другой вопрос и отлично работает. Приложение Ассоциатора файлов дважды проверяет операционную систему, используемую пользователем, и не запускается, если операционная система Vista или более поздней версии и приложение не было запущено с правами администратора. Я сделал это, так как пользователь мог напрямую запускать внешнее приложение. Код, который я использовал, был таким:
var safeToRun = true;
var os = Environment.OSVersion;
if (os.Version.Major > 5) {//Got Vista or Win7
if (!IsElevated) {
var message = new StringBuilder();
message.AppendLine("You are running Vista or Win7 and this program ");
message.AppendLine("needs to run with Admin Privileges. When the ");
message.AppendLine("program closes please right click on the executable");
message.AppendLine("or icon and select 'Run As Administrator'.");
message.AppendLine("");
message.AppendLine("The Program will now close.");
MessageBox.Show(message.ToString(), "Insufficient Privileges", MessageBoxButtons.OK, MessageBoxIcon.Error);
safeToRun = false;
}
}
if (safeToRun) {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
IsElevated проверяет текущие привилегии:
public static bool IsElevated {
get {
return new WindowsPrincipal
(WindowsIdentity.GetCurrent()).IsInRole
(WindowsBuiltInRole.Administrator);
}
}
Опять же, это не мой код, а из другого ответа.
Хотя я уверен, что у кого-то найдется лучший способ сделать это. Мое внешнее приложение-WinForm, хотя это может быть командная строка.
РЕДАКТИРОВАТЬ Следуя комментариям и предложениям Дэвида, я знаю, что это не очень хороший способ что-то делать. Однако я надеюсь, что общий вопрос и ответы (особенно комментарии Дэвида) будут поучительными для других
Комментарии:
1. Ваш подход к UAC испорчен. Вы должны просто отметить в манифесте для своего приложения, что приложению требуется повышение (
requireAdministrator
), и система либо повысит, если учетные данные могут быть предоставлены, либо завершит работу. Это очень плохой ход — делать это самому.2. Спасибо, Дэвид. Я очень признателен вам за ваши комментарии и комментарии. Я прекратил попытки работать описанным выше способом и использую Ассоциации файлов для каждого пользователя