使用Inno安装程序更新DLL服务器

使用Inno安装程序更新DLL服务器,dll,inno-setup,pascal,updates,regsvr32,Dll,Inno Setup,Pascal,Updates,Regsvr32,如果用户第一次安装我的应用程序,我如何构造Inno安装脚本以自动注册dll,但如果有以前的版本,则取消注册,然后注册新版本(假设接口不同) 我目前在“我的文件”部分中使用regserver和ignoreversion标志,如下所示: [Setup] ... [Languages] ... [Files] Source: "C:\example.dll"; DestDir: "{app}"; Flags: ignoreversion regserver 在我的谷歌搜索中我找到了,但我不知道如

如果用户第一次安装我的应用程序,我如何构造Inno安装脚本以自动注册dll,但如果有以前的版本,则取消注册,然后注册新版本(假设接口不同)

我目前在“我的文件”部分中使用regserver和ignoreversion标志,如下所示:

[Setup]
...

[Languages]
...

[Files]
Source: "C:\example.dll"; DestDir: "{app}"; Flags: ignoreversion regserver
在我的谷歌搜索中我找到了,但我不知道如何将其添加到我的脚本中。我很乐意开始修补,看看这是如何工作的,但我不想做任何会弄乱我的注册表的事情

有一篇类似的帖子,但它没有说明这是如何实现的

编辑

在使用Pascal进行黑客攻击之后,我能够将以下内容添加到[代码]部分,并且工作正常有人知道如何使用{app}常量在下面的代码中动态定义文件名吗?

[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;

在文件安装前使用和安装后使用参数怎么样

用途是:

[Files]
Source: "MYDLL.DLL"; DestDir: "{app}"; BeforeInstall: MyBeforeInstall; AfterInstall: MyAfterInstall;
BeforeInstall和AfterInstall函数不能有返回值

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;

试试这个,它还处理32/64位并行COM服务器:

函数UnregisterCOMServer(sServerCLSID:String):布尔值; 变量 sServerPath:字符串; 开始 结果:=假; //在HKCR中搜索(合并视图) 如果RegQueryStringValue(HKEY_CLASSES_ROOT,'CLSID\'+sServerCLSID+'\InprocServer32','',sServerPath),则 开始 如果路径为“”,则 开始 日志('找到COM服务器CLSID:'+sServerCLSID+',路径:'+sServerPath'); 结果:=注销服务器(False、sServerPath、True); 如果是结果,则记录('COM服务器'+sServerCLSID+'unregistered')) else日志(“+sServerPath+”上的注销服务器失败!”); 结束 else日志('未找到COM服务器路径'); 结束 else日志('COM服务器CLSID:'+sServerCLSID+'未找到!'+sServerPath)

如果是64b安装模式,则
开始
如果RegQueryStringValue(HKEY_CLASSES_ROOT,'Wow6432Node\CLSID\'+sServerCLSID+'\InprocServer32','',sServerPath),则
开始
如果路径为“”,则
开始
日志('找到COM服务器(Wow6432)CLSID:'+sServerCLSID+',路径:'+sServerPath');
结果:=取消注册服务器(True,sServerPath,True);
如果是结果,则记录('COM服务器(Wow6432)'+sServerCLSID+'Unregisted')
else日志(“+sServerPath+”上的注销服务器(Wow6432)失败!”;
结束
else日志('未找到COM服务器(Wow6432)路径');
结束
else日志('COM服务器(Wow6432)CLSID:'+sServerCLSID+'未找到!'+sServerPath);
结束;

结束

初始化设置
时展开
{app}
常量为时过早。此外,
{app}
常量包含当前选择的安装文件夹,同时您要检查以前的应用程序文件夹。您可以从
InitializeWizard
事件方法(例如:Tlama)中最快从
向导表单.PrevAppDir
属性获取最后一个文件夹,谢谢!我想知道为什么我不能引用{app}。WizardForm.PrevAppDir是如何工作的?我是否必须保持.iss脚本不变,以便向导知道以前使用过此向导?通常情况下,您不应该充分更改COM接口,使其不兼容(您应该只进行添加,而不进行减法)。因此,永远不需要注销旧版本。当然,当它是应用程序专用库而不是共享库时,您会有更多的回旋余地。我的印象是,如果我在接口上添加新的方法调用,我将需要注销以前的COM接口并重新注册新接口(使用相同的GUID)。不是这样吗?@Michael,
WizardForm.PrevAppDir
只是一个保存文件夹路径的属性,具有特定名称的安装程序以前在其中安装过应用程序(如果尚未安装,则为空)。换句话说,除非更改脚本中的
AppId
,否则此属性将返回上一个安装文件夹路径。一旦你改变了AppId,它就会被视为一个不同的设置。我喜欢这个,听起来很简单。我会看看能不能用排爆弹来测试一下。我还没有一个售后安装的用途,但它是伟大的知道。 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;