2011-02-11 20 views
12

背景:
我有一個主要應用程序,需要能夠訪問網絡並下載與其關聯的DLL文件我們編寫的,位於我們的服務器上)。它確實需要能夠將這些DLL文件下載到「C:\ Program Files \」中的應用程序文件夾中。在過去,我用System.Net.WebClient從網上下載我想要的任何文件。關於在C#中爲應用程序編寫背景/自動/無聲下載程序/安裝程序的問題#

The Issue
我在過去下載數據並保存到用戶硬盤上的文件時遇到了很多問題。我收到很多用戶的報告,說這不起作用,一般是因爲程序中存在用戶權限問題。

在程序用戶權限有問題的情況下,每個用戶都可以訪問Web上的確切文件位置,然後將其下載並手動保存到正確的位置。

我希望它能像我在其中看到的下載/安裝的所有其他程序一樣工作(例如,火狐插件更新,Flash播放器,JAVA,Adobe Reader等)。所有這些工作順利。

問題
是否有一些代碼需要用於將我的下載程序授予Program Files文件夾特殊權限?我甚至可以這樣做嗎?我應該使用更好的課程還是圖書館?是否有不同的方法來下載我應該使用的文件,例如使用線程或其他方式下載數據?

這裏的任何幫助表示讚賞。如果可能的話,我想嘗試遠離第三方應用程序/庫,當然,除了微軟之外,由於許可問題,我仍然會按照自己的方式發送任何建議。

同樣,其他程序似乎有權利問題和下載能力。我想要這個相同的能力。

+0

是啊...這是一個很好的問題。在Mac上,我會使用Sparkle http://sparkle.andymatuschak.org/,但我很好奇,看看是否有類似.NET開發的東西。 – phillip 2011-02-11 19:53:01

+0

點擊一次是在這種情況下去的路。這是字面上點擊一次。每次您的應用程序啓動時,它都會檢查您的服務器,看看是否有更新並自動更新應用程序或文件。 – 2011-02-11 20:21:25

+0

@Shiv:ClickOnce不會安裝到「程序文件」中,即它只安裝當前用戶的應用程序。 – Heinzi 2011-02-14 08:51:55

回答

3

通常的方式做到這一點是這樣的:

  1. 你的應用程序檢測到需要更新。
  2. 您的應用程序啓動另一個(更新程序)應用程序,它將下載所需的文件並將其安裝到Program Files中。此更新程序應用程序必須以管理權限運行(即在Vista/Win7中提示UAC提升)。確保這個最簡單的方法是add an application manifest to that updater application

如果用戶是啓用了UAC的管理員,則點2將導致出現必須接受的UAC提示(請注意,對於Firefox/Acrobat /等更新程序也是如此)。如果用戶不是管理員,他將被要求提供管理員憑證。 (請注意,這是一件好事:只允許管理員升級爲所有用戶安裝的應用程序。)

您的更新程序不需要用特殊方式寫入:它可以像以前一樣使用System.Net.WebClient。應用程序清單將確保它請求寫入Program Files所需的預備。

請注意,此問題(Program Files由管理員在沒有UAC提升的情況下不可寫入)是操作系統功能而非編程語言限制,因此您不會僅通過「使用不同的庫」來解決此問題。如果您希望您的應用程序在Vista/Win7上運行並寫入Program Files,那麼您的將會需要UAC提升。

0

在Vista/Win7上寫入Program Files目錄需要UAC提升(如果用戶啓用了)。看到這個代碼示例如何提示用戶的權限:http://msdn.microsoft.com/en-us/library/aa970890.aspx

真的,請考慮設計您的應用程序,以便它寫入更適當的地方,這是不會意外覆蓋重要的程序文件的風險。

-2

不要這樣做。

理論上可以很容易地完成。你只需要午餐另一個應用程序,它以管理權限運行 - 你可以在配置中請求這些應用程序在更新程序應用程序中,您只需連接到安全(ssl)網站,下載您需要的所有內容,您下載的文件必須以加密方式簽名。

這也可以很容易地解決使用ClickOnce或其他網絡安裝程序,能夠更新。

你不應該做的只是從未經驗證的源下載不安全的DLL並執行它們。

0

它確實需要在Program Files中嗎?我在應用程序中遇到過類似的問題,我們編寫了一個類來解決未安裝的程序集,方法是首先嚐試從%usersprofile%的子文件夾加載它們,然後嘗試下載。如果您將解析方法添加到當前應用程序域的AssemblyResolve事件中,這可以是無縫的。

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

     //try to download 
     return assembly; 
    } 
相關問題