用Inno Setup更新DLL服务器
问题描述:
如何构建我的Inno Setup脚本,以便在用户第一次安装我的应用程序时自动注册dll,但如果有先前版本,则注销以前的版本,然后注册新版本(假设界面不同)?用Inno Setup更新DLL服务器
我目前使用的REGSERVER和ignoreversion国旗在我的文件部分,如下图所示:
[Setup]
...
[Languages]
...
[Files]
Source: "C:\example.dll"; DestDir: "{app}"; Flags: ignoreversion regserver
在我的谷歌搜索,我发现UnregisterServer但我不知道如何将它添加到我的脚本。我很乐意开始修改,看看它是如何工作的,但我不想做任何会弄乱我的注册表的事情。
有一个类似的帖子here但它并没有解决这是如何实际完成的。
编辑
帕斯卡尔黑客周围后我能到以下添加到[代码]部分,它的工作。 有谁知道如何使用{app}常量在下面的代码中动态定义fileName?
[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;
答
怎么样使用BeforeInstall和AfterInstall参数文件?
用法为:
[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;
+0
我喜欢这个,听起来很简单。我会看看我是否可以通过eod来测试。我还没有使用AfterInstall,但很了解它。 – 2013-05-02 15:22:37
答
尝试这一个,它也可以处理32位/ 64位侧由端COM服务器:
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;
端;
在'InitializeSetup'时间扩展'{app}'常量为时过早。此外,'{app}'常量包含当前选择的安装文件夹,而您想检查以前的应用程序文件夹。您可以从'InitializeWizard'事件方法中最快从'WizardForm.PrevAppDir'属性获取最后一个文件夹,例如['这种方式'](http://pastebin.com/pkXAgEzH)。 – TLama 2013-05-02 15:03:22
Tlama,谢谢你!我想知道为什么我不能引用{app}。 WizardForm.PrevAppDir如何工作?我是否必须保持我的.iss脚本相同,以便向导知道此向导之前已被使用过? – 2013-05-02 15:19:31
通常情况下,你不应该改变COM接口,以便它们不兼容(你应该只添加,从不减)。因此永远不需要注销旧版本。当然,如果它是一个应用程序私有库而不是共享库,那么它会有更多的余地。 – Miral 2013-05-02 20:46:08