In my program I use the Running Object Table (ROT) to ensure only one instance of my program is running. Since I \"inherit\" that code from a developer who unfortunately lef
From this site it appears it could be due to a registry setting or due to the security settings on an object registered in the table:
Check "HKLM\Software\Network OLE\Enabled". Fail the request if zero. Check "HKCU\Software\Network OLE\Enabled". Fail the request if zero. Before performing any operation against a ROT entry (i.e., IRunningObjectTable::Revoke, IRunningObjectTable::IsRunning, IRunningObjectTable::GetObject, IRunningObjectTable::NoteTimeChange, IRunningObjectTable::GetTimeOfLastChange, or when including an entry in an IEnumMoniker::Next of an IEnumMoniker returned from IRunningObjectTable::EnumRunning), check the call against the SECURITY_DESCRIPTOR available from IRunningObjectTable::Register. This will be either the value returned by the object's IActivationSecurity::GetSecurityDescriptor at the time of IRunningObjectTable::Register or will have been taken from "HKCU\Software\Network OLE\DefaultROTSecurity" or "HKLM\Software\Network OLE\DefaultROTSecurity" at the time of IRunningObjectTable::Register if the object did not support IActivationSecurity.
In my experience the probability of a GUID collision, while possible appears unlikely, so it was not investigated. The first track I took was looking what could cause the AccessDeniedException
. Working backward from there you can see that GetDisplayName does not explicitly throw this exception (or return anything similar).
So what does? Your code appears to be in C#. Unless I am mistaken using COM from C# will go through a primary interop. There are only two (2) interops that expose an IMoniker
interface that I could find:
System.Runtime.InteropServices.ComTypes
contains IMonikerMicrosoft.VisualStudio.OLE.Interop
contains one as well IMonikerYou are talking about an application so my gut tells me you are using the runtime version. Looking at the calls I could not find a call returning any form of an Access Denied HRESULT
or simething similar. The VisualStudio
interop does mention the following about access and trust: Using Libraries from Partially Trusted Code. This sounded like a path to follow and would apply if your are using the Visual Studio interops.
If you are using the runtime services namespace which is contained in the mscorlib.dll
assembly (which according to this page .NET Framework Assemblies Callable by Partially Trusted Code is marked as callable partially trusted code) the explanation does not appear to apply.
So now what? I did a search for AccessDeniedException
and found no supported implementation other than an Microsoft.Office.Server.ApplicationRegistry.Infrastructure.AccessDeniedException class that is marked as obsolete in MSDN. The class is filed under the SharePoint 2010 class library.
So here are my questions: Which interop are you using? Is SharePoint in the mix at all? I said previously GUID collision was not suspected but now I am questioning that assumption. Are you requesting the proper object from the ROT? Is this object running under another process (meaning not yours)?
Perhaps this isn't the answer you are looking for, but having inherited this code, have you stopped to question if this was even the right technique for your use case? This is the first time I've seen a C# app use Com Interop for something like preventing multiple app instances. I've never had good experiences with Com and found similar unexplained or undocumented exceptions.
Why not take a look at an alternative technique for preventing multiple application instances? I have used a Mutex in past solutions of mine and never had an issue. While I don't have my past code handy, this issue has been covered several times before on stackoverflow with some pretty good answers that have been peer reviewed and community edited.
For example 'What is a good pattern for using a Global Mutex in C#?' has a good community edited answer that seems to take into account all sorts of odd ball race conditions and thread/process terminations as well as the potential security issues.
So my recommendations would be to step away from Com Interop and grab a Mutex implementation instead.