Skip to content

Commit

Permalink
Unregister .iss association from both HKCU and HKLM, and remove all t…
Browse files Browse the repository at this point in the history
…he conditional deletion code.


Before the "Open with" menu existed, if an app wanted to add itself to an existing association's context menu without taking over the association completely, it had to modify the ProgID key of whatever app owned the association. To allow for that, we previously were very careful to only delete keys/values under InnoSetupScriptFile that we created.

But there's no longer any need for that. If an app wants an "Open with" item, it should register its own ProgID and add a value under ".iss\OpenWithProgids" linking to it.
  • Loading branch information
jordanrussell authored Dec 31, 2024
1 parent 4b05dce commit c45b79d
Showing 1 changed file with 16 additions and 89 deletions.
105 changes: 16 additions & 89 deletions Projects/Src/IDE.FileAssocFunc.pas
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function GetRootkey: HKEY;
Result := HKEY_CURRENT_USER;
end;

procedure UnregisterISSFileAssociationDo(const Rootkey: HKEY; const ChangeNotify: Boolean); forward;
procedure UnregisterISSFileAssociationDo(const Rootkey: HKEY); forward;

function RegisterISSFileAssociation(const AllowInteractive: Boolean; var AllUsers: Boolean): Boolean;

Expand Down Expand Up @@ -85,108 +85,35 @@ function RegisterISSFileAssociation(const AllowInteractive: Boolean; var AllUser

{ If we just associated for all users, remove our existing association for the current user if it exists. }
if AllUsers then
UnregisterISSFileAssociationDo(HKEY_CURRENT_USER, False);
UnregisterISSFileAssociationDo(HKEY_CURRENT_USER);

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

procedure UnregisterISSFileAssociationDo(const Rootkey: HKEY; const ChangeNotify: Boolean);

function KeyValueEquals(const Rootkey: HKEY; const Subkey: PChar; const Data: String): Boolean;
var
K: HKEY;
S: String;
begin
Result := False;
if RegOpenKeyExView(rvDefault, Rootkey, Subkey, 0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
if RegQueryStringValue(K, nil, S) and (PathCompare(Data, S) = 0) then
Result := True;
RegCloseKey(K);
end;
end;

function KeyExists(const Rootkey: HKEY; const Subkey: PChar): Boolean;
var
K: HKEY;
begin
Result := (RegOpenKeyExView(rvDefault, Rootkey, Subkey, 0, KEY_QUERY_VALUE,
K) = ERROR_SUCCESS);
if Result then
RegCloseKey(K);
end;

function GetKeyNumSubkeysValues(const Rootkey: HKEY; const Subkey: PChar;
var NumSubkeys, NumValues: DWORD): Boolean;
var
K: HKEY;
begin
Result := False;
if RegOpenKeyExView(rvDefault, Rootkey, Subkey, 0, KEY_QUERY_VALUE, K) = ERROR_SUCCESS then begin
Result := RegQueryInfoKey(K, nil, nil, nil, @NumSubkeys, nil, nil,
@NumValues, nil, nil, nil, nil) = ERROR_SUCCESS;
RegCloseKey(K);
end;
end;

procedure DeleteValue(const Rootkey: HKEY; const Subkey, ValueName: PChar);
var
K: HKEY;
begin
if RegOpenKeyExView(rvDefault, Rootkey, Subkey, 0, KEY_SET_VALUE, K) = ERROR_SUCCESS then begin
RegDeleteValue(K, ValueName);
RegCloseKey(K);
end;
end;

var
SelfName: String;
NumSubkeys, NumValues: DWORD;
procedure UnregisterISSFileAssociationDo(const Rootkey: HKEY);
begin
if not KeyExists(Rootkey, 'Software\Classes\InnoSetupScriptFile') and
not KeyExists(Rootkey, 'Software\Classes\.iss') and
not KeyExists(Rootkey, 'Software\Classes\Applications\Compil32.exe') then
Exit;

SelfName := NewParamStr(0);
{ Remove 'InnoSetupScriptFile' entirely. We own it. }
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey,
'Software\Classes\InnoSetupScriptFile');

{ NOTE: We can't just blindly delete the entire .iss & InnoSetupScriptFile
keys, otherwise we'd remove the association even if we weren't the one who
registered it in the first place. }

{ Clean up 'InnoSetupScriptFile' }
if KeyValueEquals(Rootkey, 'Software\Classes\InnoSetupScriptFile\DefaultIcon', SelfName + ',1') then
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey, 'Software\Classes\InnoSetupScriptFile\DefaultIcon');
if KeyValueEquals(Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\open\command', '"' + SelfName + '" "%1"') then
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\open');
if KeyValueEquals(Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\OpenWithInnoSetup\command', '"' + SelfName + '" "%1"') then
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\OpenWithInnoSetup');
if KeyValueEquals(Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\Compile\command', '"' + SelfName + '" /cc "%1"') then
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey, 'Software\Classes\InnoSetupScriptFile\shell\Compile');
RegDeleteKeyIfEmpty(rvDefault, Rootkey, 'Software\Classes\InnoSetupScriptFile\shell');
if KeyValueEquals(Rootkey, 'Software\Classes\InnoSetupScriptFile', 'Inno Setup Script') and
GetKeyNumSubkeysValues(Rootkey, 'Software\Classes\InnoSetupScriptFile', NumSubkeys, NumValues) and
(NumSubkeys = 0) and (NumValues <= 1) then
RegDeleteKey(Rootkey, 'Software\Classes\InnoSetupScriptFile');

{ Clean up '.iss' }
if not KeyExists(Rootkey, 'Software\Classes\InnoSetupScriptFile') and
KeyValueEquals(Rootkey, 'Software\Classes\.iss', 'InnoSetupScriptFile') then begin
DeleteValue(Rootkey, 'Software\Classes\.iss', nil);
DeleteValue(Rootkey, 'Software\Classes\.iss', 'Content Type');
end;
RegDeleteKeyIfEmpty(rvDefault, RootKey, 'Software\Classes\.iss');
{ Leave '.iss' as-is. Other apps may have added their own OpenWithProgids
values there, and Microsoft docs recommend against trying to delete the
key's default value (which points to a ProgID). See:
https://learn.microsoft.com/en-us/windows/win32/shell/fa-file-types
}

{ Remove unnecessary key set by previous versions }
RegDeleteKeyIncludingSubkeys(rvDefault, Rootkey,
'Software\Classes\Applications\Compil32.exe');

if ChangeNotify then
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

procedure UnregisterISSFileAssociation;
begin
UnregisterISSFileAssociationDo(GetRootkey, True);
UnregisterISSFileAssociationDo(HKEY_CURRENT_USER);
if IsAdminLoggedOn then
UnregisterISSFileAssociationDo(HKEY_LOCAL_MACHINE);

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nil, nil);
end;

end.

0 comments on commit c45b79d

Please sign in to comment.