多年来,此代码在实用程序中运行良好。我们最近更新了程序以强制执行 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 在提升的进程中运行时不返回名字对象但在不以管理员身份运行时返回列表有任何想法?