2012-05-14 28 views
2

我有一個服務,在安裝時將Myapp.exe.config文件(基於app.config文件生成)放入安裝目錄。在安裝過程中,我需要此文件的詳細信息來配置安裝。特別是我需要調整服務的ServiceProcessInstaller實例的帳戶/用戶名/密碼字段,以便在運行時以特定用戶身份運行。在安裝時設置.NET Windows服務的角色...從app.config設置

然而,在安裝過程中,安裝程序並沒有爲我的註冊表設置,但也不能複製我的Myapp.exe.config到安裝目錄...所以我也沒辦法拉這些值,這意味着我的服務不能安裝爲正確的用戶。我現在可以做的唯一方法是將用戶/傳遞值硬編碼到ProjectInstaller類中,但我不能讓自己這樣做。這只是錯誤的。

是否有關於如何安裝服務作爲特定用戶以及如何在安裝過程中訪問這些憑據的Windows安裝最佳做法。

目前我想是這樣的:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <appSettings> 
     <add key="User" value="DOMAIN\bob"/> 
     <add key="Password" value="secret"/> 
    </appSettings> 
</configuration> 

我怎麼能拉期間安裝,而不訴諸這些用戶名/密碼值

namespace MyService 
{ 
    [RunInstaller(true)] 
    public partial class ProjectInstaller : System.Configuration.Install.Installer 
    { 
     public ProjectInstaller() 
     { 
     InitializeComponent(); 

     //Set the user credentials. 
     //NOTE: Eventually this needs to be updated to pull these values out of a 
     //  conf file. The problem now is that the location of the conf file 
     //  is tied to a registry entry for the location of the service which 
     //  may or may not exist when this block is executed. 
     /* This is the only way I can get it to work, but this is 
      * too horrible to ever actually do it this way: 
     serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.User; 
     serviceProcessInstaller1.Username = "DOMAIN\\user"; 
     serviceProcessInstaller1.Password = "password"; 
      */ 

     // Try to pull the service's registry values to know where it installed: 
     RegistryKey keyService = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\MyService"); 
     string path = ((string)keyService.GetValue("ImagePath")); 
     path = path.Substring(1, path.LastIndexOf('\\')); 

     string user = someValueFromFileIOontheAbovePath1, 
       pass = someValueFromFileIOontheAbovePath2; 

     serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.User; 
     serviceProcessInstaller1.Username = user; 
     serviceProcessInstaller1.Password = pass; 
     //Doesn't work because install isn't complete and there aren't reg settings 
     // yet, and even if I had the path the .config file is not written yet so 
     // there's no file to parse. 
     } 
    } 
} 

保存這些參數有些config文件將它們硬編碼到二進制文件中?

謝謝。

+1

您是否使用內置於Visual Studio中的MSI設置? –

+0

@ErikPhilips感謝您的評論。無論如何,我在我的解決方案中添加了一個簡單的部署項目(vdproj),該解決方案在構建時會發出設置和.msi文件。雖然真正所有的部署項目都會訪問服務內部的ServiceProcessInstaller對象。 – kmarks2

回答

1

完成MSI所需的一種方法是在提交上使用自定義操作來運行自定義對象安裝程序。提交操作在文件被複制後運行,因此這些文件將存在於用戶選擇的安裝目錄中。

+0

謝謝Erik。在提交我知道我可以運行一些其他的可執行文件,但有什麼方法可以訪問我的服務代碼中的ServiceProcessInstaller?我不知道有任何其他地方可以實際設置用戶/傳遞,而不是在服務本身中嵌入此對象的代碼。 – kmarks2

+1

我幾乎總是把自己的windows服務編寫成帶有參數的自安裝程序,然後在提交時手動運行EXE。這是我個人的偏好,因爲如果安裝程序本身損壞或exe/msi發生了什麼情況,手動刪除服務可能非常痛苦。 –

2

有很多不同級別的安全選項。

1)如果指定ServiceAccount.User但不給一個用戶名和密碼,微軟的類將彈出時,要輸入的憑據的窗口。這是非常安全的,因爲憑據永遠不會存儲在任何地方,但彈出窗口並不能真正向運行安裝程序的人員清楚他們輸入的內容。另外彈出窗口不能很好地與其他安裝屏幕流動。

2)您可以讓MSI將用戶名和密碼作爲參數傳遞給您的安裝程序類。這些值在InstallLog文件中以純文本形式保留,儘管如此,您仍然希望將其刪除。

3)讓MSI使用DPAPI(System.Security.Cryptography.ProtectedData類)對註冊表中的名稱/密碼進行加密,然後解密並在服務安裝程序類中使用它們。

+0

有趣。我不知道那是行爲。如果我不能以任何其他方式讓它工作,這是一個選項。 – kmarks2

相關問題