private void RemovePropertyHandler() { #if x64 // On 64-bit machines, remove the 32-bit property handler, as we set up both using (RegistryKey handlers = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X86). OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers", true)) { bool delete = false; using (RegistryKey handler = handlers.OpenSubKey(Name, true)) { if (handler != null) { if (handler.GetValueNames().Contains(ChainedValueName)) { var temp = handler.GetValue(ChainedValueName); handler.SetValue(null, temp); handler.DeleteValue(ChainedValueName); } else { // Only delete the sub key if it points to our handler var temp = handler.GetValue(null) as string; delete = (temp != null && temp == OurPropertyHandlerGuid32); } } } // Delete needs to happen after we have released the registry key if (delete) { handlers.DeleteSubKey(Name); } } #endif // Now, remove 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)) { if (PropertyHandlerState == HandlerState.Ours) { handlers.DeleteSubKey(Name); this.RecordPropertyHandler(HandlerState.None, null, null); } else if (PropertyHandlerState == HandlerState.Chained) { using (RegistryKey handler = handlers.OpenSubKey(Name, true)) { handler.SetValue(null, PropertyHandlerGuid); handler.DeleteValue(ChainedValueName); this.RecordPropertyHandler(HandlerState.Foreign, PropertyHandlerGuid, PropertyHandlerTitle); } } } }
// Temporary code to support MainWindow.CheckForBlockedExtensions() //public bool IsPropertyHandlerBlocked() //{ // bool result = false; // if (PropertyHandlerState == HandlerState.Foreign) // { // AddPropertyHandler(); // result = PropertyHandlerTest.WindowsIgnoresOurPropertyHandler(Name); // RemovePropertyHandler(); // } // return result; //} private void AddPropertyHandler() { #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); if (temp != null) { 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); } } } }
// Check to see if the registry entries are down level i.e. 1.3 or 1.4, and so need refreshing public bool IsRefreshRequired() { // Find the key for the extension in HKEY_CLASSES_ROOT using (RegistryKey target = GetHKCRProfileKey(true)) { // Refresh is required if old school FullDetails value is present if (target != null && target.GetValue(FullDetailsValueName) != null) { return(true); } } #if x64 // On 64-bit machines, check that we have a 32-bit property handler, as we now set up both using (RegistryKey handlers = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X86). OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers", true)) { using (RegistryKey handler = handlers.OpenSubKey(Name, false)) { // It is important to get the criteria right here, as we don't want to // return a positive unless removing the handler and setting it up again // will resolve the situation // If there is no handler, refresh is required if (handler == null || handler.GetValue(null) == null) { return(true); } // Also refresh if we are chained, and no original property handler is recorded (even if null) else if (PropertyHandlerState == HandlerState.Chained && !handler.GetValueNames().Contains(ChainedValueName)) { return(true); } } } #endif return(false); }
public void RemoveHandlerFromExtension() { if (!IsElevated) { throw new AssocMgrException { Description = LocalizedMessages.AdminPrivilegesNeeded, Exception = null, ErrorCode = WindowsErrorCodes.ERROR_ACCESS_DENIED } } ; if (PropertyHandlerState != HandlerState.Ours && PropertyHandlerState != HandlerState.Chained) { return; } // Now find the key for the extension in HKEY_CLASSES_ROOT using (RegistryKey target = GetHKCRProfileKey(true)) { // Tolerate the case where the extension has been removed since we set up a handler for it // We still do this even though no longer write entries here so as to be sure to clean up after earlier versions, // and to restore pre-existing entries if we had to hide them if (target != null) { RemoveProgidRegistryEntries(target); } } // Now go after the settings in SystemFileAssociations // We may have created the key for the extension, but we can't tell, so we just remove the values using (RegistryKey target = GetSystemFileAssociationsProfileKey(true)) { if (target != null) { RemoveProgidRegistryEntries(target); } } #if x64 // On 64-bit machines, remove the 32-bit property handler, as we set up both using (RegistryKey handlers = RegistryExtensions.OpenBaseKey(RegistryHive.LocalMachine, RegistryExtensions.RegistryHiveType.X86). OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers", true)) { bool delete = false; using (RegistryKey handler = handlers.OpenSubKey(Name, true)) { if (handler != null) { if (handler.GetValueNames().Contains(ChainedValueName)) { var temp = handler.GetValue(ChainedValueName); handler.SetValue(null, temp); handler.DeleteValue(ChainedValueName); } else { // Only delete the sub key if it points to our handler var temp = handler.GetValue(null) as string; delete = (temp != null && temp == OurPropertyHandlerGuid32); } } } // Delete needs to happen after we have released the registry key if (delete) { handlers.DeleteSubKey(Name); } } #endif // Now, remove 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)) { if (PropertyHandlerState == HandlerState.Ours) { handlers.DeleteSubKey(Name); this.RecordPropertyHandler(HandlerState.None, null, null); this.Profile = null; } else // Chained { using (RegistryKey handler = handlers.OpenSubKey(Name, true)) { handler.SetValue(null, PropertyHandlerGuid); handler.DeleteValue(ChainedValueName); this.RecordPropertyHandler(HandlerState.Foreign, PropertyHandlerGuid, PropertyHandlerTitle); this.Profile = null; } } } State.HasChanged = true; }
// 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); if (temp != null) { 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; }