示例#1
0
        // Setup the registry entries required when an extension is given our handler
        public void SetupHandlerForExtension(Profile selectedProfile, bool createMergedProfile)
        {
            if (!IsElevated)
            {
                throw new AssocMgrException
                      {
                          Description = LocalizedMessages.AdminPrivilegesNeeded,
                          Exception   = null,
                          ErrorCode   = WindowsErrorCodes.ERROR_ACCESS_DENIED
                      }
            }
            ;

            if (PropertyHandlerState != HandlerState.None && PropertyHandlerState != HandlerState.Foreign)
            {
                throw new AssocMgrException
                      {
                          Description = String.Format(LocalizedMessages.ExtensionAlreadyHasHandler, Name),
                          Exception   = null,
                          ErrorCode   = WindowsErrorCodes.ERROR_INVALID_PARAMETER
                      }
            }
            ;

            Profile profile;

            // Work out what profile to set up
            if (PropertyHandlerState == HandlerState.None || !createMergedProfile)
            {
                profile = selectedProfile;
            }
            else
            {
                // We use a custom profile with the same name as the extension
                profile = State.CustomProfiles.FirstOrDefault(p => p.Name == Name);

                // If it doesn't already exist, create it
                if (profile == null)
                {
                    profile = new Profile {
                        Name = this.Name, State = this.State
                    };
                    State.CustomProfiles.Add(profile);
                }
                // If we're recycling the profile, clone it to preserve its original values
                else if (profile == selectedProfile)
                {
                    selectedProfile = selectedProfile.CreateClone();
                }
            }

            // Find the key for the extension in HKEY_CLASSES_ROOT
            using (RegistryKey target = GetHKCRProfileKey(true))
            {
                // We used to place entries on this key, but no longer do, because such keys can be shared,
                // and we only want to affect a specific extension
                // We still have to hide any existing entries, because otherwise they would take priority, but fortunately they do not often occur
                // If there are entries, and we are merging, we read them into the new profile, in case this is the only place they occur
                if (PropertyHandlerState == HandlerState.Foreign)
                {
                    GetAndHidePreExistingProgidRegistryEntries(target, createMergedProfile ? profile : null);
                }
            }

            // Now we only update the extension specific area
            using (RegistryKey target = GetSystemFileAssociationsProfileKey(true))
            {
                if (PropertyHandlerState == HandlerState.Foreign)
                {
                    if (createMergedProfile)
                    {
                        GetAndHidePreExistingProgidRegistryEntries(target, profile);

                        // Merge the selected profile into any entries that came with the foreign handler
                        profile.MergeFrom(selectedProfile);
                    }
                    else
                    {
                        GetAndHidePreExistingProgidRegistryEntries(target, null);
                    }
                }

                SetupProgidRegistryEntries(target, profile);
            }

            if (PropertyHandlerState == HandlerState.Foreign)
            {
                // Write the updated custom profile information back to the store
                State.StoreUpdatedProfile(profile);
            }

#if x64
            // On 64-bit machines, set up the 32-bit property handler, so that 32-bit applications can also access our properties
            using (RegistryKey handlers = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X86).
                                          OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers", true))
            {
                using (RegistryKey handler = handlers.CreateSubKey(Name))
                {
                    if (PropertyHandlerState == HandlerState.None)
                    {
                        var temp = handler.GetValue(null);
                        // In the case where there is no 64-bit handler, but there is a 32-bit handler, leave it alone
                        if (temp == null)
                        {
                            handler.SetValue(null, OurPropertyHandlerGuid32);
                        }
                    }
                    else // Foreign
                    {
                        var temp = handler.GetValue(null);
                        handler.SetValue(null, OurPropertyHandlerGuid32);
                        handler.SetValue(ChainedValueName, temp);
                    }
                }
            }
#endif
            // Now, add the main handler extension key, which is 32- or 64-bit, depending on how we were built
            // The 32-bit and 64-bit values of these are separate and isolated on 64-bit Windows,
            // the 32-bit value being under SOFTWARE\Wow6432Node.  Thus a 64-bit manager is needed to set up a 64-bit handler
            using (RegistryKey handlers = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers", true))
            {
                using (RegistryKey handler = handlers.CreateSubKey(Name))
                {
                    if (PropertyHandlerState == HandlerState.None)
                    {
                        handler.SetValue(null, OurPropertyHandlerGuid);
                        this.RecordPropertyHandler(HandlerState.Ours, null, null);
                    }
                    else // Foreign
                    {
                        handler.SetValue(null, OurPropertyHandlerGuid);
                        handler.SetValue(ChainedValueName, PropertyHandlerGuid);
                        this.RecordPropertyHandler(HandlerState.Chained, PropertyHandlerGuid, PropertyHandlerTitle);
                    }
                }
            }

            this.Profile = profile;

            State.HasChanged = true;
        }