在安装Inno Setup的过程中,我正在将文件添加到zip存档中,请参见此处:Inno Setup Copy Files and Folders to an Existing Zip File。添加文件后,我立即通过将文件扩展名从.zip更改为.doc来重命名了存档。
用于重命名的代码是:
RenameFile(ExpandConstant('{app}\MyFile.zip'), expandconstant('{app}\MyFile.doc'))
虽然以前在Windows 7和Windows 8上可以很好地工作,但是它变得不那么可靠,有时只能在Windows 10上工作。
注意,我尝试过的事情包括:
sleep(###);
个间隔,但这不起作用... 正在寻找提出可靠解决方案的建议和/或调试技巧。
[编辑:添加了代码...重命名了一些位以使其更易于阅读]
function SetFileAttributes(lpFileName : String; dwAttribs : LongInt) : Boolean;
external 'SetFileAttributesA@kernel32.dll stdcall';
procedure RepackZip();
var
ResultCode, i: Integer;
x1, x2: string;
begin
// Find files
x1 := FindFile('xmlns="sl:SLA"');
x2 := FindFile('xmlns="sl:SLB"');
log(ExpandConstant('{app}'));
// 2. Copy files to archive
SetFileAttributes ((expandconstant('{app}\MyFile.zip')), 0);
if not FileCopy(ExpandConstant('{tmp}\SLA.xml'), ExpandConstant('{app}\Temp\customXml\') + x1, False) then
MsgBox(x1 + 'failed!', mbError, MB_OK);
if not FileCopy(ExpandConstant('{tmp}\SLB.xml'), ExpandConstant('{app}\Temp\customXml\') + x2, False) then
MsgBox(x2 + 'failed!', mbError, MB_OK);
CopyToArchive();
SetFileAttributes ((expandconstant('{app}\MyFile.zip')), 0);
sleep(100);
// HAVE TRIED COPY & RENAME
// Everything works up to here and both FileCopy and FileRename fail on the same computers (permissions?)
// Have told Inno to Require Admin, makes no difference.
//RenameFile(ExpandConstant('{app}\MyFile.zip'), expandconstant('{app}\MyFile.dotm'))
FileCopy(ExpandConstant('{app}\MyFile.zip'), ExpandConstant('{app}\MyFile.doc'), false);
For i := 0 to 5 do
begin
if not FileExists(ExpandConstant('{app}\MyFile.doc')) then
begin
sleep (250);
end
else begin
// SetFileAttributes ((expandconstant('{app}\MyFile.doc')), 1);
exit;
end;
end;
if not FileExists(expandconstant('{app}\MyFile.doc')) then
MsgBox('Failed - rename archive to .doc', mbError, MB_OK);
end;
然后使用CopyToArchive(此方法有效-但我想知道CopyToArchive是否可能以某种方式将存档保持打开状态并阻止重命名):
procedure CopyToArchive(); //(const Archive, Content: string);
var
Shell: Variant;
Folder: Variant;
Archive, Content: string;
objFSO, h: Variant;
max0, max1: integer;
begin
Shell := CreateOleObject('Shell.Application');
Archive := ExpandConstant('{app}') + '\MyFile.zip';
Folder := Shell.NameSpace(Archive);
log('Archive Location: ' + Archive);
objFSO := CreateOleObject('Scripting.FileSystemObject');
h := objFSO.getFile(Archive);
Content := ExpandConstant('{app}\Temp\customXml\');
Folder.CopyHere(Content, $0100);
sleep(2000);
end;
我开始研究的一件事是使用objFSO重命名存档,但我无法弄清楚...
答案 0 :(得分:1)
有两个问题:
.CopyHere
调用是异步的。调用后,您必须等待归档完成。尽管Sleep
并非真正可行,但应该可以。 .CopyHere
实际上不会锁定文件,因此不会阻止重命名,但是您最终可能会重命名不完整的文件。objFSO.getFile(Archive)
的调用,该调用将锁定文件,并且您永远都无法将其解锁。实际上,您从不使用h
。因此,请删除该呼叫。为什么在归档之前不重命名文件?这样可以避免所有这些问题。