0

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

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...

SlowLearner
  • 3,086
  • 24
  • 54
  • Thanks will take a look anyway for anyone interested, WiX: http://wixtoolset.org/ – SlowLearner Oct 10 '18 at 11:31
  • MS use themselves to author the SQL Installer ... – Jammer Oct 10 '18 at 11:31
  • So I installed WiX and... if I click on the WiX Toolset it just takes me back to the website from whence it came... Exit. Search WiX, open the desktop app and huh? So... let me get this straight... here is an installer that can't even install itself?? – SlowLearner Oct 10 '18 at 11:38
  • Never had an issue installing WiX. Once installed you author installers using Visual Studio by creating a WiX project. – Jammer Oct 10 '18 at 11:40
  • Oh... I'm not actually using VS, I'm in VBA (from within MS Office itself)... so if I open VS.... – SlowLearner Oct 10 '18 at 11:43
  • @MartinPrikryl - have added what I think is relevant, pls let me know if more is needed - thank you! – SlowLearner Oct 10 '18 at 21:37
  • The Pascal script you showed uses legacy Windows API to manipulate files, which no one can guarantee correctness always. If possible, use modern things, like PowerShell, to execute the same operation, and then call the PowerShell script from Inno Setup. – Lex Li Oct 11 '18 at 04:02
  • Thanks @LexLi - I'll see what I can find for PowerShell, thanks for the pointer :-) – SlowLearner Oct 11 '18 at 04:44

1 Answers1

1

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.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thanks, I'll do some testing around that and report back. I think I tried with `h` commented out but it didn't help, I might put a ridiculously long sleep duration... – SlowLearner Oct 11 '18 at 06:26
  • commenting out the `h` and adding a stupid big delay (20sec) worked, now... I'll see how small I can make the delay. – SlowLearner Oct 11 '18 at 07:55