Маршал.GetActiveObject () выбрасывает Mk E недоступное исключение в C#
следующий код vbscript работает нормально:
Dim App
Set App = GetObject("","QuickTest.Application")
App.Quit
но когда я перевожу его в код C#, как показано ниже:
class Program
{
[STAThread]
static void Main(string[] args)
{
object qtApp = Marshal.GetActiveObject("QuickTest.Application");
(qtApp as QuickTest.Application).Quit();
}
}
Я получаю исключение:
необработанное исключение типа System.Во время выполнения.InteropServices.COMException ' произошло в mscorlib.dll файлы
дополнительная информация: (исключение из HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
Я не думаю, что проблема связана с ROT, потому что код vbscript работает. Так что не так с кодом C#?
3 ответов
Маршал.GetActiveObject используйте progID, проверьте свой progID, например, вы можете использовать этот код для отображения объектов в 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));
}
}
}
Я обнаружил, что запуск отладчика/IDE с повышенными привилегиями (т. е. режим администратора) может вызвать эту проблему, когда процесс вы пытаетесь определить работает без повышенных привилегий.
проблема также может быть вызвана не запуск с повышенными привилегиями. Это, похоже, изменилось с годами, поэтому попробуйте все перестановки запуска IDE или целевой программы с повышенными привилегиями или без них.
по состоянию на август 2017 года, чтобы получить запущенный экземпляр Outlook 365 под отладчиком Visual Studio 2015, мне пришлось сделать следующее, Чтобы избежать ошибки MK_E_UNAVAILABLE:
- запустить Outlook как Администратор!--8-->
- запустите Visual Studio как администратор
моя программа, запущенная в отладчике, смогла успешно получить запущенный экземпляр Outlook.