Reputation: 3071
How do I structure my Inno Setup script to automatically register a dll if it is the first time a user has installed my application but unregister a previous version if there is one and then register the new one (assuming the interface is different)?
I currently use the the regserver and ignoreversion flags in my Files section as seen below:
[Setup]
...
[Languages]
...
[Files]
Source: "C:\example.dll"; DestDir: "{app}"; Flags: ignoreversion regserver
In my google search I have found UnregisterServer but I not know how to add this to my script. I would gladly start tinkering around to see how this works, but I do not want to do anything that will mess-up my registry.
There is a similar post here but it does not address how this is actually accomplished.
EDIT
After hacking around in Pascal I was able to add the following to the [Code] section and it worked. Does anyone know how to use the {app} constant to dynamically define the fileName in the code below?
[Code]
const
fileName = 'C:\Program Files\TFolderName\tigercontroller.dll';
var
serverExists: Boolean;
function InitializeSetup(): Boolean;
begin
serverExists := UnregisterServer(False, fileName, False);
if serverExists then begin
Result:= True;
MsgBox('This will update with the most recent version', mbInformation, mb_Ok);
end else
Result := True;
end;
Upvotes: 1
Views: 1934
Reputation: 71
Try this one, it also handles 32/64bit side-by-side COM servers:
function UnregisterCOMServer(sServerCLSID: String): Boolean;
var
sServerPath: String;
Begin
Result:=False;
//search in HKCR (merged view)
if RegQueryStringValue(HKEY_CLASSES_ROOT, 'CLSID\'+sServerCLSID+'\InprocServer32', '', sServerPath) then
Begin
if sServerPath<>'' then
Begin
Log('Found COM server CLSID:'+ sServerCLSID +', path:'+sServerPath);
Result:=UnregisterServer(False, sServerPath, True);
if Result then Log('COM server '+ sServerCLSID +' unregistered.')
else Log('UnregisterServer on '+ sServerPath +' failed!');
end
else Log('No COM server path found.');
end
else Log('COM server CLSID:'+ sServerCLSID +' not found!'+sServerPath);
if Is64BitInstallMode then
Begin
if RegQueryStringValue(HKEY_CLASSES_ROOT, 'Wow6432Node\CLSID\'+sServerCLSID+'\InprocServer32', '', sServerPath) then
Begin
if sServerPath<>'' then
Begin
Log('Found COM server (Wow6432) CLSID:'+ sServerCLSID +', path:'+sServerPath);
Result:=UnregisterServer(True, sServerPath, True);
if Result then Log('COM server (Wow6432) '+ sServerCLSID +' unregistered.')
else Log('UnregisterServer (Wow6432) on '+ sServerPath +' failed!');
end
else Log('No COM server (Wow6432) path found.');
end
else Log('COM server (Wow6432) CLSID:'+ sServerCLSID +' not found!'+sServerPath);
end;
end;
Upvotes: 0
Reputation: 5472
What about using BeforeInstall and AfterInstall parameters for file?
Usage is:
[Files]
Source: "MYDLL.DLL"; DestDir: "{app}"; BeforeInstall: MyBeforeInstall; AfterInstall: MyAfterInstall;
BeforeInstall and AfterInstall functions must not have a return value!
procedure MyBeforeInstall();
begin
// Your code here: If file (old) file exists call UnregisterServer() on old file
// Use function FileExists(const Name: String): Boolean; or similar for it
// Also you can delete the file entirely with function DeleteFile(const FileName: string): Boolean;
// Hint: You can use 'CurrentFileName' variable to get currently processed file
end;
procedure MyAfterInstall();
begin
// Your (new) file was processed and now you can do additional tweaks on it
// 'CurrentFileName' variable is still available
// Setup registers all files with the 'regserver' or 'regtypelib' flags as the last step of installation so in this function the file is still not registered!
end;
Upvotes: 2