访问运行对象表时出现问题

Fis*_*aen 21 c# running-object-table

在我的程序中,我使用运行对象表(ROT)来确保只运行一个程序实例.由于我从一位不幸离开公司的开发人员那里"继承"了这段代码,我是解决问题的穷人.代码工作正常,但我们有3个客户(39,000个)将获得AccessDeniedException.每个客户都以用户模式运行软件.

有什么建议可能是错的吗?

bool retVal = false;
IMoniker[] arrMoniker = new IMoniker[1];
IBindCtx bindCtx = null;
string displayName;
int hResult;
int mkSys;
Guid clsidRot;
bool guidCompare = false;

IntPtr number = IntPtr.Zero;
moreObjectsListed = false;
objectFromRot = null;

try
{
    // check the objects in the running object table for fitting the specified class id
    while ((retVal == false) && (0 == enumMoniker.Next(1, arrMoniker, number)))
    {
        hResult = CreateBindCtx(0, out bindCtx);
        if (hResult == 0)
        {
            arrMoniker[0].IsSystemMoniker(out mkSys);

            if (mkSys == 4)
            {
                try
                {
                    // the display name is the class id of the object in the table
                    // --> AccessDeniedException raises here <--
                    arrMoniker[0].GetDisplayName(bindCtx, null, out displayName);
                    clsidRot = new Guid(displayName.Substring(1));  
                    guidCompare = clsidRot.Equals(clsid);
                }
                catch(Exception) {}

                // an object with fitting class id was found
                if (guidCompare == true)
                {
                    rot.IsRunning(arrMoniker[0]);
                    rot.GetObject(arrMoniker[0], out objectFromRot);
                    retVal = true;
                }
            }
        }
    }
}
finally
{
    if (arrMoniker[0] != null)
    {
        moreObjectsListed = true;
        Marshal.ReleaseComObject(arrMoniker[0]);
    }
    if (bindCtx != null)
    {
        Marshal.ReleaseComObject(bindCtx);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是在ROT中注册对象的请求代码:

internal static extern uint RegisterActiveObject([MarshalAs(UnmanagedType.IUnknown)]object pIUnknown, ref Guid refclsid, uint flags, out uint pdwRegister);
internal const uint ActiveObjectStrong = 0;

...

NativeMethods.RegisterActiveObject(this, ref guid, NativeMethods.ActiveObjectStrong, out this.runningObjectTableRegisteredId);
Run Code Online (Sandbox Code Playgroud)

编辑2:

首先是所有调查员的一个大EXCUSE,我们没有得到AccessDeniedException它是一个System.UnauthorizedAccessException(HRESULT:0x80070005(E_ACCESSDENIED)).

第二个问题的答案为"调查员"肯布里泰恩的问题: - 的SharePoint不是在混合-也许这3个问题1(除39000工作正常)正在运行的另一种暗示-我'舒尔从ROT请求正确的对象WTS上的应用程序(Windows终端服务器)

编辑3:

这是一个例外的堆栈跟踪:(我已经翻译了堆栈跟踪,因为它是在德国机器上)

System.UnauthorizedAccessException: Access denied (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
at System.Runtime.InteropServices.ComTypes.IRunningObjectTable.EnumRunning(IEnumMoniker& ppenumMoniker)
at Datev.Framework.DirectStart.RunningObjectTableClientManager..ctor()
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪的其余部分在我们的代码中.在这种情况下可标记的是在RunningObjectTableClientManager的构造函数中引发异常.这是构造函数的代码:

private IRunningObjectTable rot;
private IEnumMoniker enumMoniker;

public RunningObjectTableClientManager()
{
    int retVal = GetRunningObjectTable(0, out this.rot);

    if (retVal == 0)
    {
        rot.EnumRunning(out this.enumMoniker);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ken*_*ain 5

根据我的经验,GUID碰撞的可能性虽然可能不太可能,但是没有进行调查.我拍的第一首曲目是寻找导致这种情况的原因AccessDeniedException.从那里向后工作,您可以看到GetDisplayName没有显式抛出此异常(或返回任何类似的异常).

那是什么?您的代码似乎是在C#中.除非我错误地使用来自C#的COM将通过主互操作.只有两(2)个interops暴露了IMoniker我可以找到的接口:

  • System.Runtime.InteropServices.ComTypes包含IMoniker
  • Microsoft.VisualStudio.OLE.Interop 包含一个以及IMoniker

你在谈论一个应用程序,所以我的直觉告诉我你正在使用运行时版本.看着这些电话,我找不到任何形式的拒绝访问 HRESULT或类似的访问.在VisualStudio互操作未提到有关访问和信任以下内容:从部分信任的代码使用库.这听起来像一条路径,如果你正在使用Visual Studio interops,它将适用.

如果您正在使用程序集中包含的运行时服务命名空间mscorlib.dll(根据此页面,.NET Framework程序集可由部分受信任的代码调用被标记为可调用的部分受信任的代码),则说明似乎不适用.

那么现在怎么办?我搜索AccessDeniedException并发现除了在MSDN中标记为过时Microsoft.Office.Server.ApplicationRegistry.Infrastructure.AccessDeniedException类之外没有任何受支持的实现.该类是在SharePoint 2010类库下提交的.

所以这是我的问题:你使用哪个互操作?SharePoint是否在混合中?我之前说过GUID碰撞没有被怀疑,但现在我在质疑这个假设.你是从ROT请求正确的对象吗?此对象是否在另一个进程(不是你的进程)下运行?