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;
            }
        }
        /// <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);
            }
        }