在使用 Inno Setup 更新之前压缩本地文件
Posted
技术标签:
【中文标题】在使用 Inno Setup 更新之前压缩本地文件【英文标题】:Zip local files prior to an update with Inno Setup 【发布时间】:2013-11-07 09:24:51 【问题描述】:在运行我的安装程序的新版本时,我想通过将文件添加到 ZIP 存档来备份现有安装。
目前,我可以通过将文件复制到我的Backup
目标来备份现有安装。我使用的方法的简化版本如下:
[Files]
; Copy the contents of Bin folder to Backup folder. Skip if files don’t exist.
Source: app\Bin\*; DestDir: app\Backup\; \
Flags: createallsubdirs external recursesubdirs uninsneveruninstall skipifsourcedoesntexist;
如果有任何想法可以代替压缩,我将不胜感激?
【问题讨论】:
我认为例如7-zip 或 zlib DLL 可用于打包文件(如果可以将其函数导出转换为 Inno Setup)。或者,您可以自己编写一个非常简单的单用途 DLL(正如我所看到的,您是一名本地语言程序员)。 【参考方案1】:您可能想查看 LOGAN ISSI:http://members.home.nl/albartus/inno/index.html 捆绑了一些实用程序。
另一种方法是包含一个批处理文件,该文件将执行备份步骤,然后在完成后将其自行删除。
签出这个帖子:Batch script to zip all the files without the parent folder
但是,由于许可,您不允许将 rar.dll 与您的应用程序捆绑,因此只需应用此方法,但使用可重新分发的包/dll。
如果您可以使用 VBScript 编写一个简单的包装器,您也可以使用内置 zip 压缩的 windows。
看看你怎么样:Can Windows' built-in ZIP compression be scripted?
【讨论】:
【参考方案2】:我使用了 TLama 的建议,并在 Delphi (XE3) 中创建了自己的 DLL,用于压缩文件夹。
library MyZipLib;
uses
Winapi.Windows,
System.SysUtils,
System.Zip;
$R *.res
function ZipCompressFolder(SourcePath, DestinationPath, ArchiveName : PChar): boolean; stdcall;
begin
//If source folder does not exist then exit without error.
if not DirectoryExists(SourcePath) then
begin
result := true;
exit;
end;
try
result := false;
//Make sure destination path exists
ForceDirectories(DestinationPath);
TZipFile.ZipDirectoryContents(IncludeTrailingPathDelimiter(DestinationPath) + ArchiveName, SourcePath);
result := true;
except
on E : Exception do MessageBox(0, PChar('Error calling function ZipCompressFolder@MyZipLib.dll with message: ' + E.Message + #13#10 + 'Source: ' + SourcePath + #13#10 + 'Dest: ' + DestinationPath+ #13#10 + 'Archive: ' + ArchiveName), 'MyZipLib.dll Error', MB_OK);
end;
end;
exports ZipCompressFolder;
begin
end.
【讨论】:
【参考方案3】:如果您知道要在具有 .NET 4.5 和更高版本(即 Windows 8 和更高版本)的计算机上进行安装,则可以使用 PowerShell 和 .NET 4.5 ZipFile
class from CurStepChanged(ssInstall)
event function。
[Code]
procedure CurStepChanged(CurStep: TSetupStep);
var
Command, AppPath, ZipName, ZipTmpPath, ZipPath: string;
ResultCode: Integer;
begin
if CurStep = ssInstall then
begin
AppPath := ExpandConstant('app');
if not DirExists(AppPath) then
begin
Log(Format('Application path "%s" does not exist, ' +
' probably fresh install, not backing up', [AppPath]));
end
else
begin
ZipName := 'backup.zip';
ZipTmpPath := ExpandConstant('tmp') + '\' + ZipName;
ZipPath := AppPath + '\' + ZipName;
if FileExists(ZipPath) then
begin
if DeleteFile(ZipPath) then
Log(Format('Archive ZIP "%s" exists, deleted', [ZipPath]))
else
RaiseException(Format(
'Archive ZIP "%s" exists, and it could not be deleted', [ZipPath]));
end;
Log(Format('Archiving application folder "%s" to temporary "%s"', [
AppPath, ZipTmpPath]));
Command :=
'Add-Type -Assembly System.IO.Compression.FileSystem ; ' +
'[System.IO.Compression.ZipFile]::CreateFromDirectory(''' +
AppPath + ''', ''' + ZipTmpPath +''')';
if Exec('powershell', '-ExecutionPolicy Bypass -command "' + Command + '"',
'', SW_HIDE, ewWaitUntilTerminated, ResultCode) and
(ResultCode = 0) then
begin
Log(Format('Application folder "%s" archived to temporary "%s"', [
AppPath, ZipTmpPath]));
end
else
begin
RaiseException(Format('Error archiving application folder "%s" "%s"', [
AppPath, ZipTmpPath]));
end;
if FileCopy(ZipTmpPath, ZipPath, False) then
Log(Format('Copied "%s" to "%s"', [ZipTmpPath, ZipPath]))
else
RaiseException(Format('Error copying "%s" to "%s"', [
ZipTmpPath, ZipPath]));
end;
end;
end;
如果您需要支持更旧版本的 Windows,您可以使用 Shell.Application
类。虽然我无法让它创建一个 ZIP 文件,但只能添加一个。一个解决方案可能是将一个空的 ZIP 文件添加到安装程序中,然后添加到它。
【讨论】:
以上是关于在使用 Inno Setup 更新之前压缩本地文件的主要内容,如果未能解决你的问题,请参考以下文章