簡體   English   中英

如何以管理員身份運行時讓IEnumMoniker.Next返回monikers?

[英]How can I get IEnumMoniker.Next to return monikers when running as administrator?

此代碼在實用程序中運行良好多年。 我們最近更新了程序以強制執行UAC,但我們發現此代碼僅在不以管理員身份運行時才有效; 當以管理員身份運行時,while循環中的代碼永遠不會執行,但是相同的代碼在運行不正確時返回名字對象名稱列表。

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

namespace ROTExplorer
{
    class Program
    {
    [DllImport("ole32.dll")]
    static extern int GetRunningObjectTable(uint reserved, out IRunningObjectTable rot);

    [DllImport("Ole32.Dll")]
    static extern int CreateBindCtx(int reserved, out IBindCtx bindCtx);

    static void Main(string[] args)
    {
        FindEntryInROT();
        Console.WriteLine("Press any key to continue.");
        Console.ReadKey();
    }

    private static string FindEntryInROT()
    {
        IRunningObjectTable rot = null;
        IBindCtx bindCtx = null;
        IEnumMoniker enumMoniker = null;
        IMoniker[] monikers = new IMoniker[1];
        string displayName = null;
        try
        {
            GetRunningObjectTable(0, out rot);
            CreateBindCtx(0, out bindCtx);
            rot.EnumRunning(out enumMoniker);
            IntPtr fetched = IntPtr.Zero;
            while (enumMoniker.Next(1, monikers, fetched) == 0)
            {
                string tempName;
                monikers[0].GetDisplayName(bindCtx, null, out tempName);
                Marshal.ReleaseComObject(monikers[0]);
                monikers[0] = null;
                try
                {
                    Console.WriteLine(tempName);
                }
                catch
                {
                    Console.WriteLine("Bad string");
                }
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Failure while examining ROT: " + ex.Message);
        }
        finally
        {
            ReleaseCOMObject(monikers[0]);
            ReleaseCOMObject(enumMoniker);
            ReleaseCOMObject(bindCtx);
            ReleaseCOMObject(rot);
        }
        Console.WriteLine(displayName);
        return displayName;
    }

    private static void ReleaseCOMObject(object comObject)
    {
        if (comObject != null)
        {
            Marshal.ReleaseComObject(comObject);
            comObject = null;
        }
    }

}

我在2台機器上試過這個。 其他人可以嘗試這個並確認此代碼僅在不以管理員身份運行時返回名字對象列表。

有沒有人想過為什么IEnumMoniker在升級過程中運行時沒有返回monikers,但在不以admin身份運行時返回列表?

我和微軟開了一張票。 它升級了,我終於得到了答案:它按設計工作。 這是相關的對話:

微軟支持:

SCM / RPCSS服務是運行對象表所在的位置。 枚舉表時,服務會進行多次檢查。 其中一項檢查專門用於將客戶端令牌的高程級別與令牌條目的高程級別相匹配。 如果不匹配,則不會返回該條目。 您看到的行為是設計的。

我:

你能給我發一個鏈接到這里記錄的地方嗎? 具有“提升”權限應該允許用戶訪問更多對象,而不是更少。 你所描述的似乎只是簡單地以不同的用戶身份登錄。

微軟支持:

它沒有直接記錄。
在某些方面,你的最后陳述是正確的。 管理員用戶有兩個安全令牌,一個用於正常操作,另一個用於提升。 它們從未同時使用過。 https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works當管理員登錄時,會創建兩個單獨的訪問令牌用戶:標准用戶訪問令牌和管理員訪問令牌。 標准用戶訪問令牌包含與管理員訪問令牌相同的用戶特定信息,但會刪除管理Windows權限和SID。 我相信所有這些背后的原因都與安全有關,但我無法解釋這一點。

我:

管理員令牌可以訪問標准用戶的文件; 為什么用戶的COM對象與用戶的文件對象區別對待?

微軟支持:

因為這是產品組制定的設計決策。 我沒有關於他們為什么這樣做的確切原因的進一步信息。

我:

這聽起來像是我的錯誤,或者是錯誤的設計。 有沒有辦法把它放在產品組的雷達上?

微軟支持:

不幸的是,在這個領域沒有任何改變。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM