SlowLearner
SlowLearner

Reputation: 3294

Inno Setup Sometimes Fails to Change File During Installation

During an Inno Setup install I am adding files to a zip archive, see here: Inno Setup Copy Files and Folders to an Existing Zip File. I immediately after adding the files, the archive is renamed by changing the file extension from .zip to .doc.

Code used to rename is:

RenameFile(ExpandConstant('{app}\MyFile.zip'),  expandconstant('{app}\MyFile.doc'))  

While this used to work well under windows 7 and 8, it has become less reliable and only sometimes works under windows 10.

Note, things I have tried include:

Looking for suggestions to make a robust solution and or debugging tips.

[Edit: added the codes... have renamed some bits to make it easier to read]

   function SetFileAttributes(lpFileName : String; dwAttribs : LongInt) : Boolean;
   external '[email protected] 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;

And CopyToArchive (this works - but I was wondering if CopyToArchive might somehow be holding the archive open and preventing the rename):

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;

One thing that I started looking into was to use objFSO to rename the Archive, but I was unable to figure it out...

Upvotes: 0

Views: 464

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202118

There are two problems:

  • .CopyHere call is asynchronous. After you call it, you have to wait for the archiving to complete. While Sleep is not really realiable, it should do. .CopyHere actually does not lock the file, so it won't prevent the rename, but you may end up renaming an incomplete file.
  • What causes the rename to fail is your call to objFSO.getFile(Archive), which locks the file and you never unlock it. And you actually never use h. So remove that call.

Why don't you rename the file before archiving? It would prevent all these problems.

Upvotes: 1

Related Questions