Marshal.GetActiveObject() throws MK_E_UNAVAILABLE exception in C#

前端 未结 3 1160
名媛妹妹
名媛妹妹 2020-12-14 11:07

The following vbscript code works prefectly fine:

Dim App 
Set App = GetObject(\"\",\"QuickTest.Application\")
App.Quit

But when I translat

相关标签:
3条回答
  • 2020-12-14 11:15

    I found that running the debugger/IDE with elevated privileges (i.e. Admin mode) can cause this problem when the process you are trying to detect is running without elevated privileges.

    0 讨论(0)
  • 2020-12-14 11:24

    Marshal.GetActiveObject use progID , check your progID, e.g. you could use this code for display objects in ROT

    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Runtime.InteropServices.ComTypes;
    using System.Text;
    using Microsoft.Win32;
    ...
    class Program
    {
        private const int S_OK = 0x00000000;
    
        [DllImport("ole32.dll")]
        private static extern int GetRunningObjectTable(uint reserved, out IRunningObjectTable pprot);
    
        [DllImport("ole32.dll")]
        private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);      
    
        private static void OleCheck(string message, int result)
        {
            if (result != S_OK)
                throw new COMException(message, result);
        }
    
        private static System.Collections.Generic.IEnumerable<IMoniker> EnumRunningObjects()
        {           
            IRunningObjectTable objTbl;
            OleCheck("GetRunningObjectTable failed", GetRunningObjectTable(0, out objTbl));
            IEnumMoniker enumMoniker;
            IMoniker[] monikers = new IMoniker[1];
            objTbl.EnumRunning(out enumMoniker);
            enumMoniker.Reset();
            while (enumMoniker.Next(1, monikers, IntPtr.Zero) == S_OK)
            {
                yield return monikers[0];
            }
        }
    
        private static bool TryGetCLSIDFromDisplayName(string displayName, out string clsid)
        {
            var bBracket = displayName.IndexOf("{");
            var eBracket = displayName.IndexOf("}");
            if ((bBracket > 0) && (eBracket > 0) && (eBracket > bBracket))
            {
                clsid = displayName.Substring(bBracket, eBracket - bBracket + 1);
                return true;
            }
            else 
            {
                clsid = string.Empty;
                return false;
            }   
        }
    
        private static string ReadSubKeyValue(string keyName, RegistryKey key)
        {
            var subKey = key.OpenSubKey(keyName);
            if (subKey != null)
            {
                using(subKey)
                {
                    var value = subKey.GetValue("");
                    return value == null ? string.Empty : value.ToString();
                }
            }
            return string.Empty;
        }
    
        private static string GetMonikerString(IMoniker moniker)
        {
            IBindCtx ctx;
            OleCheck("CreateBindCtx failed", CreateBindCtx(0, out ctx));
            var sb = new StringBuilder();
            string displayName;
            moniker.GetDisplayName(ctx, null, out displayName);
            sb.Append(displayName);
            sb.Append('\t');
            string clsid; 
            if (TryGetCLSIDFromDisplayName(displayName, out clsid))
            {
                var regClass = Registry.ClassesRoot.OpenSubKey("\\CLSID\\" + clsid);
                if (regClass != null)
                {
                    using(regClass)
                    {
                        sb.Append(regClass.GetValue(""));
                        sb.Append('\t');
                        sb.Append(ReadSubKeyValue("ProgID", regClass));
                        sb.Append('\t');
                        sb.Append(ReadSubKeyValue("LocalServer32", regClass));
                    }
                }
            }
            return sb.ToString();
        }
    
        [STAThread]
        public static void Main(string[] args)
        {
            Console.WriteLine("DisplayName\tRegId\tProgId\tServer");
            foreach(var moniker in EnumRunningObjects())
            {
                Console.WriteLine(GetMonikerString(moniker));
            }
        }
    }  
    
    0 讨论(0)
  • 2020-12-14 11:24

    The issue can also be triggered by not running with elevated privileges. This seems to have changed over the years, so try all permutations of running either the IDE or the target program with or without elevated privileges.

    As of August 2017, to get the running instance of Outlook 365 under the Visual Studio 2015 debugger, I had to do the following to avoid the MK_E_UNAVAILABLE error:

    • Start Outlook as Administrator
    • Start Visual Studio as Administrator

    My program running in the debugger was then able to get the running instance of Outlook successfully.

    0 讨论(0)
提交回复
热议问题