2013-10-04 86 views
0

我需要一些有關權限/安裝程序的信息。安裝程序權限檢測

我目前正在一個項目中,我們需要爲我們的應用程序安裝一個安裝程序。該程序與Windows XP +兼容,所以XP,Vista,7 & 8.我需要做的是檢測當前用戶是否有權限安裝我們的應用程序。

我發現了一些關於此事的帖子,但他們都沒有給我明確的答案,我想/需要。

至於我們的架構是如下:

我們有一個「單擊一次」應用程序包含一個C++應用程序,.NET 2.0「Windows應用程序」 &一個.NET 4.0「Windows應用程序」 - 的C++應用程序相當簡單,它基本上只是檢測他們已經安裝的.NET版本,並委託給該Windows應用程序。這些Windows應用程序中的每一個都基本相同 - 它們基本上會執行連接速度檢查,如果它通過它下載併爲我們的軟件運行相應的MSI安裝程序。

用戶顯然需要能夠有權限安裝我們的應用程序,我們需要在此鏈中的某處添加檢測(圍繞Windows應用程序中的速度檢查或MSI安裝程序的一部分,米不知道 - 這是我需要人們的幫助)。

什麼是最好的方式去做到這一點,以及如何?

從我可以告訴他們將是一些UAC周圍的複雜性(無論是,關&無論他們是本地管理員,域管理員或只是一個普通用戶,如果他們是一個域用戶,而不是目前網絡)。他們也會有一些其他的複雜性,因爲我們還需要補償沒有UAC的XP(實際上我不確定如何檢測XP)。

從我在網上看到有一些選項做它的代碼,例如這樣:In .NET/C# test if process has administrative privileges

還有周圍清單等一些其他的選項:How do I force my .NET application to run as administrator? - 將清單式方法工作在XP?

我有幾個選擇沿着這條管道與哪裏添加這個,所以我從社區中尋找的是關於在哪裏/如何爲我所有的要求做到這一點的信息。

任何人都可以提供的幫助將不勝感激。

感謝, 邁克爾

回答

0

不知道的最佳做法,但如果你想檢測用戶是否擁有管理員權限或者通過他們的帳戶在管理員組中正在或如果他們有升級到能力通過UAC的作用,看看對於自我升級的MSDN代碼示例:http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3/sourcecode?fileId=21729&pathId=1041468146

這個例子有一個方法MainForm.IsUserInAdminGroup()看起來在任當前用戶的令牌或它們的升級令牌:

/// <summary> 
/// The function checks whether the primary access token of the process belongs 
/// to user account that is a member of the local Administrators group, even if 
/// it currently is not elevated. 
/// </summary> 
/// <returns> 
/// Returns true if the primary access token of the process belongs to user 
/// account that is a member of the local Administrators group. Returns false 
/// if the token does not. 
/// </returns> 
/// <exception cref="System.ComponentModel.Win32Exception"> 
/// When any native Windows API call fails, the function throws a Win32Exception 
/// with the last error code. 
/// </exception> 
internal bool IsUserInAdminGroup() 
{ 
    bool fInAdminGroup = false; 
    SafeTokenHandle hToken = null; 
    SafeTokenHandle hTokenToCheck = null; 
    IntPtr pElevationType = IntPtr.Zero; 
    IntPtr pLinkedToken = IntPtr.Zero; 
    int cbSize = 0; 

    try 
    { 
     // Open the access token of the current process for query and duplicate. 
     if (!NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle, 
      NativeMethods.TOKEN_QUERY | NativeMethods.TOKEN_DUPLICATE, out hToken)) 
     { 
      throw new Win32Exception(); 
     } 

     // Determine whether system is running Windows Vista or later operating 
     // systems (major version >= 6) because they support linked tokens, but 
     // previous versions (major version < 6) do not. 
     if (Environment.OSVersion.Version.Major >= 6) 
     { 
      // Running Windows Vista or later (major version >= 6). 
      // Determine token type: limited, elevated, or default. 

      // Allocate a buffer for the elevation type information. 
      cbSize = sizeof(TOKEN_ELEVATION_TYPE); 
      pElevationType = Marshal.AllocHGlobal(cbSize); 
      if (pElevationType == IntPtr.Zero) 
      { 
       throw new Win32Exception(); 
      } 

      // Retrieve token elevation type information. 
      if (!NativeMethods.GetTokenInformation(hToken, 
       TOKEN_INFORMATION_CLASS.TokenElevationType, pElevationType, 
       cbSize, out cbSize)) 
      { 
       throw new Win32Exception(); 
      } 

      // Marshal the TOKEN_ELEVATION_TYPE enum from native to .NET. 
      TOKEN_ELEVATION_TYPE elevType = (TOKEN_ELEVATION_TYPE) 
       Marshal.ReadInt32(pElevationType); 

      // If limited, get the linked elevated token for further check. 
      if (elevType == TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited) 
      { 
       // Allocate a buffer for the linked token. 
       cbSize = IntPtr.Size; 
       pLinkedToken = Marshal.AllocHGlobal(cbSize); 
       if (pLinkedToken == IntPtr.Zero) 
       { 
        throw new Win32Exception(); 
       } 

       // Get the linked token. 
       if (!NativeMethods.GetTokenInformation(hToken, 
        TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, 
        cbSize, out cbSize)) 
       { 
        throw new Win32Exception(); 
       } 

       // Marshal the linked token value from native to .NET. 
       IntPtr hLinkedToken = Marshal.ReadIntPtr(pLinkedToken); 
       hTokenToCheck = new SafeTokenHandle(hLinkedToken); 
      } 
     } 

     // CheckTokenMembership requires an impersonation token. If we just got 
     // a linked token, it already is an impersonation token. If we did not 
     // get a linked token, duplicate the original into an impersonation 
     // token for CheckTokenMembership. 
     if (hTokenToCheck == null) 
     { 
      if (!NativeMethods.DuplicateToken(hToken, 
       SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, 
       out hTokenToCheck)) 
      { 
       throw new Win32Exception(); 
      } 
     } 

     // Check if the token to be checked contains admin SID. 
     WindowsIdentity id = new WindowsIdentity(hTokenToCheck.DangerousGetHandle()); 
     WindowsPrincipal principal = new WindowsPrincipal(id); 
     fInAdminGroup = principal.IsInRole(WindowsBuiltInRole.Administrator); 
    } 
    finally 
    { 
     // Centralized cleanup for all allocated resources. 
     if (hToken != null) 
     { 
      hToken.Close(); 
      hToken = null; 
     } 
     if (hTokenToCheck != null) 
     { 
      hTokenToCheck.Close(); 
      hTokenToCheck = null; 
     } 
     if (pElevationType != IntPtr.Zero) 
     { 
      Marshal.FreeHGlobal(pElevationType); 
      pElevationType = IntPtr.Zero; 
     } 
     if (pLinkedToken != IntPtr.Zero) 
     { 
      Marshal.FreeHGlobal(pLinkedToken); 
      pLinkedToken = IntPtr.Zero; 
     } 
    } 

    return fInAdminGroup; 
}