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

マニフェストに関する他のオプションもあります。たとえば、.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 に答える