/// <summary> /// Registers the COM object under the given name. The returned /// IDisposable must be disposed in order to remove the object /// from the table, otherwise resource leaks may result (I think). /// </summary> public IDisposable Register(string itemName, object obj) { IMoniker mk = CreateMoniker(itemName); // The ALLOW_ANY_CLIENT setting will be set to true if we've been launched via 'Run as administrator' at // least once because this means we wrote the HKLM registry entries to allow passing the // ROTFLAGS_ALLOWANYCLIENT flag. var exeRegistrySettings = new RegistrySettingsPersister(Registry.CurrentUser, EXE_REGISTRY_PATH); bool allowAnyClient = (bool)exeRegistrySettings.Get(ALLOW_ANY_CLIENT, typeof(bool), false); int rotRegistrationFlags = allowAnyClient ? (int)(RunningObjectTableFlags.RegistrationKeepsAlive | RunningObjectTableFlags.AllowAnyClient) : (int)(RunningObjectTableFlags.RegistrationKeepsAlive); try { int registration = _rot.Register(rotRegistrationFlags, obj, mk); return(new RegistrationHandle(this, registration)); } catch (COMException ex) { Trace.Fail("Exception thrown from IRunningObjectTable::Register: \r\n" + ex); // If registration failed, try again without ROTFLAGS_ALLOWANYCLIENT because the AllowAnyClient setting might be out of date. exeRegistrySettings.Set(ALLOW_ANY_CLIENT, false); rotRegistrationFlags = (int)(RunningObjectTableFlags.RegistrationKeepsAlive); int registration = _rot.Register(rotRegistrationFlags, obj, mk); return(new RegistrationHandle(this, registration)); } }
public static void EnsureComRegistration() { // Are we running with Administrator privileges? If so, we need to write to HKLM. Otherwise, need to write to HKCU. RegistryKey rootKey = IsInAdministratorRole ? Registry.LocalMachine : Registry.CurrentUser; try { // A client calling IRunningObjectTable::Register with the ROTFLAGS_ALLOWANYCLIENT bit must have its // executable name in the AppID section of the registry that refers to the AppID for the executable. var exeRegistrySettings = new RegistrySettingsPersister(rootKey, EXE_REGISTRY_PATH); exeRegistrySettings.Set("AppID", APP_ID); // A RunAs entry must be present because the system prohibits "activate as activator" processes from registering in // the ROT with ROTFLAGS_ALLOWANYCLIENT.This is done for security reasons. var appIdRegistrySettings = new RegistrySettingsPersister(rootKey, APP_ID_REGISTRY_PATH); appIdRegistrySettings.Set("", "OpenLiveWriter.exe"); appIdRegistrySettings.Set("RunAs", "Interactive User"); if (IsInAdministratorRole) { // If we wrote to HKLM, even medium integrity processes can now use ROTFLAGS_ALLOWANYCLIENT. // However, medium integrity processes can't read from HKLM to see if it's set or not, so we // need a duplicate setting to store this information. exeRegistrySettings = new RegistrySettingsPersister(Registry.CurrentUser, EXE_REGISTRY_PATH); exeRegistrySettings.Set("AllowAnyClient", true); } } catch (Exception ex) { Trace.Fail("Exception thrown while setting RunningObjectTable COM registration: \r\n" + ex); if (!RegistryHelper.IsRegistryException(ex)) { throw; } } }