Вопрос о написании фонового/автоматического/тихого загрузчика/установщика для приложения на C#

Предыстория:
у меня есть основное приложение, которое должно иметь возможность выходить в Интернет и загружать связанные с ним DLL-файлы (те, которые мы пишем, расположенные на нашем сервере). Это действительно должно быть в состоянии загрузить эти файлы DLL в папку приложения в "C:\Program Files\". В прошлом я использовал System.Net.WebClient для загрузки любых файлов из Интернета.

Проблема
Раньше у меня возникали проблемы со скачиванием данных и их сохранением в файлы на жестком диске пользователя. Я получаю много сообщений от пользователей, говорящих, что это не работает, и обычно это происходит из-за проблем с правами пользователя в программе.

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

Я хочу, чтобы это работало, как и все другие программы, которые я видел для загрузки/установки в этой моде (например, Firefox Pluign Updates, Flash Player, JAVA, Adobe Reader и т. д.). Все это работает без сбоев.

Вопрос
Есть ли какой-то код, который мне нужно использовать, чтобы дать моей программе-загрузчику специальные права на папку Program Files? Могу ли я сделать это? Есть ли лучший класс или библиотека, которую я должен использовать? Есть ли другой подход к загрузке файлов, например, использование потоков или что-то еще для загрузки данных?

Любая помощь здесь приветствуется. Я хочу стараться держаться подальше от сторонних приложений/библиотек, если это вообще возможно, кроме Microsoft, конечно, из-за проблем с лицензированием, но все же присылать любые предложения по-своему.

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


person Mike Webb    schedule 11.02.2011    source источник
comment
да... это хороший вопрос. На Mac я бы использовал Sparkle sparkle.andymatuschak.org, но мне интересно узнать, есть ли что-нибудь как это разработано для .NET.   -  person phillip    schedule 11.02.2011
comment
Щелкните один раз — это путь в этом случае. Это буквально щелчок один раз. Каждый раз, когда ваше приложение запускается, оно проверяет ваш сервер на наличие обновлений и автоматически обновляет приложение или файлы.   -  person Shiv Kumar    schedule 11.02.2011
comment
@Shiv: ClickOnce не устанавливается в Program Files, т. Е. Он устанавливает приложение только для текущего пользователя.   -  person Heinzi    schedule 14.02.2011


Ответы (6)


Обычный способ сделать это выглядит следующим образом:

  1. Ваше приложение обнаруживает, что требуется обновление.
  2. Ваше приложение запускает другое приложение (обновление), которое загружает необходимые файлы и устанавливает их в Program Files. Это приложение обновления должно запускаться с правами администратора (т. е. запрашивать повышение прав UAC в Vista/Win7). Самый простой способ убедиться в этом — добавить манифест приложения в это приложение обновления.

Если пользователь является администратором с включенным UAC, пункт 2 приведет к появлению запроса UAC, который необходимо принять (обратите внимание, что то же самое верно для программ обновления Firefox/Acrobat/и т. д.). Если пользователь не является администратором, у него будут запрошены учетные данные администратора. (Обратите внимание, что это хорошо: только администратору должно быть разрешено обновлять приложения, установленные для всех пользователей.)

Ваше приложение для обновления не нужно писать особым образом: оно может использовать System.Net.WebClient точно так же, как и раньше. Манифест приложения гарантирует, что оно запрашивает необходимые разрешения для записи в Program Files.

Обратите внимание, что эта проблема (Program Files недоступна для записи администраторам без повышения прав UAC) является функцией операционной системы, а не ограничением языка программирования, поэтому вы не решите эту проблему, просто «используя другую библиотеку». Если вы хотите, чтобы ваше приложение работало в Vista/Win7 и записывало в Program Files, вам потребуется повышение прав UAC.

person Heinzi    schedule 13.02.2011
comment
+1 — это функция операционной системы, а не ограничение языка программирования. - person Shiv Kumar; 15.02.2011
comment
Я много изучал это, и это лучший и наиболее широко используемый метод. - person Mike Webb; 22.02.2011

Ознакомьтесь с сервисом BITS:

http://msdn.microsoft.com/en-us/magazine/cc188766.aspx

person jvenema    schedule 11.02.2011

Для записи в каталог Program Files требуется повышение прав UAC (если это разрешено пользователем) в Vista/Win7. См. этот пример кода о том, как запрашивать у пользователей разрешение: http://msdn.microsoft.com/en-us/library/aa970890.aspx

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

person Robert Levy    schedule 11.02.2011
comment
Куда такие программы, как Adobe Reader и JAVA, устанавливают свои файлы? Я полагал, что они скачали и установили свои файлы в свои папки в Program Files. - person Mike Webb; 11.02.2011
comment
Ах, извините, я думал, вы скачиваете документы. Для загрузки DLL для вашего собственного приложения Program Files имеет смысл - person Robert Levy; 11.02.2011
comment
Важным уроком здесь является выполнение вашей разработки (или, по крайней мере, вашего тестирования) из учетной записи без прав администратора с полностью включенным UAC. - person Robert Levy; 11.02.2011
comment
Другое место, куда вы можете загрузить библиотеки DLL, — это подпапка %AppData%. Однако эта информация относится к вашему профилю пользователя. - person ; 14.02.2011

Как насчет того, чтобы попробовать http://netsparkle.codeplex.com/. Порт очень успешной платформы Mac Sparkle http://sparkle.andymatuschak.org/.

person phillip    schedule 11.02.2011

Это действительно должно быть в Program Files? У меня была аналогичная проблема в приложении, и мы написали класс для разрешения неустановленных сборок, сначала попытавшись загрузить их из подпапки %usersprofile%, а затем попытавшись загрузить. Это может быть незаметно, если вы добавите метод разрешения в событие AssemblyResolve текущего домена приложения.

    AppDomain.CurrentDomain.AssemblyResolve+= AssemblyResolve;
    public Assembly AssemblyResolve(object sender, ResolveEventArgs args)
    {
         //try to get locally

         //try to download
         return assembly;
    }
person tallseth    schedule 13.02.2011

Не делай этого.

Теоретически это можно сделать легко. вы просто запускаете другое приложение, которое работает с правами администратора — вы можете запросить их в конфигурации. В приложении обновления вы просто подключаетесь к защищенному (ssl) веб-сайту, загружаете все, что вам нужно, загружаемые файлы должны быть криптографически подписаны.

Это также можно легко решить с помощью ClickOnce или другого веб-установщика, поддерживающего обновления.

Чего вы не должны делать, так это просто загружать небезопасные DLL из непроверенного источника и запускать их.

person AK_    schedule 11.02.2011