Доступ на запись к папке Program Files

мое приложение включает исполняемый файл самообновления, который используется для обновления приложения.

Одним из первых шагов, выполняемых программой обновления, является проверка наличия у нее прав на запись в папку приложения.

IPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, _localApplicationCodebase);

        if (!SecurityManager.IsGranted(perm))
        {
            OnProgressChanged("Security Permission Not Granted \n The updater does not have read/write access to the application's files (" +
                              _localApplicationCodebase + ")",MessageTypes.Error);
            return false;
        }

        OnProgressChanged("Updater have read/write access to local application files at " + _localApplicationCodebase);
        return true;

При выполнении под Win7 / Vista этот код проходит (это означает, что, согласно CAS, у кода есть доступ на запись), однако, когда я пытаюсь записать файлы, я получаю отказ в доступе (и я подтвердил, что файлы НЕ используются)

Я понимаю, что Vista / Win7 UAC не позволяет пользователям записывать файлы в папки программных файлов. Однако я не понимаю, почему разрешение предоставляется, если на самом деле это не так.

С уважением,

Эрик Жирар

PS: Если я запустил тот же код с помощью «Запуск от имени администратора», он будет работать нормально.


person Eric Girard    schedule 11.11.2009    source источник
comment
Приложение пытается перезаписать себя во время работы?   -  person Philip Wallace    schedule 11.11.2009
comment
Как я уже писал, это не так, программа обновления - это еще один .exe, который не зависит от какой-либо локальной библиотеки DLL.   -  person Eric Girard    schedule 11.11.2009
comment
Я думаю, что если вы не являетесь администратором, вам не разрешено писать какие-либо исполняемые файлы в каких-либо подпапках программных файлов. Ваша программа обновления пытается писать исполняемые файлы?   -  person Wim ten Brink    schedule 11.11.2009
comment
Интересное чтение на msdn.microsoft.com/en-us/library/bb530410.aspx: встроить манифест приложения с соответствующим элементом requiredExecutionLevel.   -  person Wim ten Brink    schedule 11.11.2009
comment
у тебя это заработало? У меня такая же проблема...   -  person Slav    schedule 01.07.2010


Ответы (3)


О UAC важно знать, что по умолчанию ни один код не запускается с правами администратора и, следовательно, не может писать в каталог Program Files. Даже если вы вошли в систему как администратор, приложения запускаются со стандартными правами пользователя.

Есть два способа обойти это. Пользователь может запустить приложение с помощью пункта меню «Запуск от имени администратора». Но это зависит от того, что пользователь что-то помнит. Лучше было встроить манифест в свой исполняемый файл, запрашивающий права администратора. В манифесте задайте для requiredExecutionLevel значение requireAdministrator. Это приведет к тому, что UAC будет запрашивать у пользователя учетные данные администратора при запуске приложения.

Как сказал Даниэль, лучшее решение - вынести функцию обновления в отдельное приложение. У вашего основного приложения будет манифест, который устанавливает для параметра requiredExecutionLevel значение asInvoker, а ваше приложение для обновления - с запросом requireAdministrator. Ваше основное приложение может работать со стандартными привилегиями. Но когда необходимо выполнить обновление, используйте Process.Start для запуска приложения обновления, которое требует от пользователя ввода учетных данных администратора.

person epotter    schedule 11.12.2009

Лучший способ написать программу автоматического обновления - создать дополнительное приложение. Первая программа вызывает вторую с повышенными привилегиями, запрашивая UAC. Затем второе приложение может устанавливать патчи.

person Daniel A. White    schedule 11.11.2009
comment
Или заставьте приложение снова вызвать само себя с повышенными привилегиями. Если у него нет этих привилегий, он должен снова запустить себя, запрашивая у UAC дополнительные права ... - person Wim ten Brink; 11.11.2009
comment
Это именно то, что я делаю прямо сейчас, но это все еще не дает ответа на мой вопрос: почему SecurityManager.IsGranted возвращает TRUE для этой папки, если на самом деле это не разрешено для папки программных файлов? - person Eric Girard; 11.11.2009

Я не уверен, что вы пытаетесь это сделать, но я нашел этот пост полезным. Включенный код позволяет определить, работает ли ваше приложение в Vista, включен ли UAC и повышен ли пользователь.

http://www.itwriting.com/blog/198-c-code-to-detect-uac-elevation-on-vista.html

затем перезапустите приложение с помощью runas, чтобы пользователь мог повысить разрешения

ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = Application.ExecutablePath;
Process.Start(processInfo);
person Slav    schedule 05.07.2010