Search code examples
inno-setuppascalscript

Inno Setup Code section create hidden file


I am working with an Inno Setup project. The project is writing a file out using the SaveStringToFile function in the [Code] section. I would like to make this file a hidden system file, but I haven't been able to find information on how to make this work. Any ideas?


Solution

  • There is no function to set file attributes in Inno Setup Pascal Script. So either you would have to import Windows API functions that can set file attributes or use the following trick. You can create an empty file which you'll set to be hidden in the script entry and after that you can write whatever you need there, so it will be the installation process which will create a hidden file for you:

    [Files]
    ; MyFile.txt is an empty text file
    Source: "MyFile.txt"; DestDir: "{app}"; Attribs: hidden; AfterInstall: WriteToFile
    
    [Code]
    procedure WriteToFile;
    begin
      SaveStringToFile(ExpandConstant('{app}\MyFile.txt'), 'Hello!', True);
    end;
    

    For the sake of completeness I'm including also a function by which you can explicitly set hidden attribute to a file:

    [Code]
    #ifdef UNICODE
      #define AW "W"
    #else
      #define AW "A"
    #endif
    
    const
      INVALID_FILE_ATTRIBUTES = $FFFFFFFF;
    
    function GetFileAttributes(lpFileName: string): DWORD;
      external 'GetFileAttributes{#AW}@kernel32.dll stdcall';
    function SetFileAttributes(lpFileName: string; dwFileAttributes: DWORD): BOOL;
      external 'SetFileAttributes{#AW}@kernel32.dll stdcall';
    
    procedure RaiseLastOSError;
    var
      LastError: LongInt;
    begin
      LastError := DLLGetLastError;
      RaiseException(Format('System Error. Code: %d. %s', [LastError,
        SysErrorMessage(LastError)]));
    end;
    
    procedure SetFileHiddenAttr(const FileName: string);
    var
      Attrs: DWORD;
    begin
      Attrs := GetFileAttributes(FileName);
      if Attrs <> INVALID_FILE_ATTRIBUTES then
      begin
        if Attrs and FILE_ATTRIBUTE_HIDDEN = 0 then
          if not SetFileAttributes(FileName, Attrs or FILE_ATTRIBUTE_HIDDEN) then
            RaiseLastOSError;
      end
      else
        RaiseLastOSError;
    end;