Inno Setup FileExists unable to find existing file

2019-06-01 03:03发布

问题:

In my script I am checking whether a directory and two files in this directory exist. While the first returns the correct value, the second check does not. I've checked it multiple times that these files exist in the designated directory but Inno Setup will always tell me that they do not exist. This is happening on a virtual Windows Server, and can't be reproduced on my local machine. There it always returns the correct Value.

UpdatePath := ExpandConstant('{app}');
if DirExists(UpdatePath) then begin
    ExePath := UpdatePath+'\Application.exe';
    ConfigFilePath := UpdatePath+'\Application.exe.config'; 
    if FileExists(ExePath) and FileExists(ConfigFilePath) then begin //this one returns incorrect values
        //Do Stuff
    end else begin
        MsgBox(FmtMessage(CustomMessage('DirPageFileNotFound'), [ExePath, ConfigFilePath]),mbInformation,MB_OK); 
        Result := False;
    end;
end else begin
    MsgBox(FmtMessage(CustomMessage('DirPageDirectoryNotFound'), [UpdatePath]),mbInformation,MB_OK);
    Result := False;
end;

As you can see, I'm checking for an executable which can also be executed when double-clicked. It is there but Inno Setup will always tell me that it's not there. Is the virtual environment messing with it? What is happening here?

回答1:

To debug the issue, try adding following code. Then check the log file of the installer and the output of the dir command:

#ifdef UNICODE
  #define AW "W"
#else
  #define AW "A"
#endif

function GetFileAttributes(lpFileName: string): DWORD;
  external 'GetFileAttributes{#AW}@kernel32.dll stdcall'; 

function GetLastError() : LongInt;
 external 'GetLastError@kernel32.dll stdcall';

const
  INVALID_FILE_ATTRIBUTES = $FFFFFFFF;

procedure ...;
var
  UpdatePath: string;
  ExePath: string;
  FindRec: TFindRec;
  Attrs: DWORD;
  LastError: LongInt;
  ResultCode: Integer;
begin
  Log('InitializeWizard');
  UpdatePath := ExpandConstant('{app}');
  ExePath := UpdatePath+'\Application.exe';

  if FileExists(ExePath) then
  begin
    Log(ExePath + ' exists');
  end
    else
  begin
    LastError := GetLastError;
    Log(ExePath + ' does not exist - '  +
      Format('System Error. Code: %d. %s', [LastError, SysErrorMessage(LastError)]));
  end;

  if not FindFirst(UpdatePath + '\*', FindRec) then
  begin
    LastError := GetLastError;
    Log(UpdatePath + ' not found - ' +
      Format('System Error. Code: %d. %s', [LastError, SysErrorMessage(LastError)]));  
  end
    else
  begin
    repeat
      Log('Found file: ' + FindRec.Name + ' in ' + UpdatePath);
    until not FindNext(FindRec);
  end;

  Attrs := GetFileAttributes(ExePath);
  if Attrs <> INVALID_FILE_ATTRIBUTES then
  begin
    Log(ExePath + ' attributes = ' + IntToStr(Attrs));
  end
    else
  begin
    LastError := GetLastError;
    Log(Format('Cannot get attributes of ' + ExePath + ': System Error. Code: %d. %s', [
          LastError, SysErrorMessage(LastError)]));  
  end;

    Exec(ExpandConstant('{cmd}'), '/k dir "' + UpdatePath + '"', '', SW_SHOW,
      ewWaitUntilTerminated, ResultCode);
end;

The FileExists internally uses FindFirst/FindNext and GetFileAttributes. So this is to find out what causes the problem.


My wild guess is that the target machine is 64-bit and file system redirection jumps in for some reason.

Try using EnableFsRedirection to disable the redirection before you call FileExists:

EnableFsRedirection(False);