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 检测它)。

从我在网上看到的情况来看,有一些选项可以在代码中执行,例如:在 .NET/C# 中测试进程是否具有管理权限

Manifest 周围还有一些其他选项,例如:如何强制我的 .NET 应用程序以管理员身份运行?- 清单类型的方法可以在 XP 上使用吗?

我在这个管道上有几个选项,可以在哪里添加它,所以我从社区中寻找的是关于在哪里/如何为我的所有要求执行此操作的信息。

任何人都可以提供的任何帮助将不胜感激。

谢谢,迈克尔

4

1 回答 1

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; 
}
于 2013-10-11T03:21:44.013 回答