安装程序权限检测

本文关键字:检测 权限 程序 安装 | 更新日期: 2023-09-27 18:33:46

我需要一些关于权限/安装程序的信息。

我目前正在进行一个项目,我们需要为我们的应用程序安装一个安装程序。该程序与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# 中测试进程是否具有管理权限

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

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

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

谢谢迈克尔

安装程序权限检测

不确定最佳做法

,但如果要检测用户是否通过其帐户位于管理员组中而具有管理员权限,或者他们是否能够通过 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; 
}