what causes this error 'Unable to write to application file.ini'

前端 未结 2 1610
夕颜
夕颜 2021-01-22 08:44

My application is build in delphi and it runs perfect on other platforms except Windows 7 64bit machine. Each and everytime try to close the application is giving me this error

相关标签:
2条回答
  • 2021-01-22 09:29

    This error is usually caused by trying to write to your app's own folder under Program Files, which is not allowed for a non-Administrator under Vista and higher (and XP, if you're not running as an Administrator or Power User).

    Here's some code for getting the proper folder for your .INI file:

    uses
      Windows,
      ShlObj;   // For SHGetSpecialFolderPath
    
    function GetFolderLocation(Handle: HWnd; Folder: Integer): string;
    begin
      Result := '';
      SetLength(Result, MAX_PATH);
      if not SHGetSpecialFolderPath(Handle, PChar(Result), Folder, False) then
        RaiseLastOSError;
    end;
    

    I use these in my application to retrieve the non-roaming profile folder, and use a sub-folder created beneath that for my app's data. It's set up during the creation of a TDataModule:

    procedure TAppData.Create(Sender.TObject);
    begin
      // DataPath is a property of the datamodule, declared as a string
      // CSIDL_LOCAL_APPDATA is the local non-roaming profile folder.
      // CSIDL_APPDATA is for the local roaming profile folder, and is more typically used
      DataPath := GetFolderLocation(Application.Handle, CSIDL_LOCAL_APPDATA);
      DataPath := IncludeTrailingPathDelimiter(DataPath) + 'MyApp\';
    end;
    

    See MSDN's documentation page on the meaning of the various CSIDL_ or FOLDERID_ values. The FOLDERID_ values are similar, but are available only on Vista and above and used with SHGetKnownFolderIDList.

    For those of you not willing to disregard MS's warnings about SHGetSpecialFolderPath not being supported, here's an alternate version of GetFolderLocation using SHGetFolderPath, which is preferred:

    uses
      ShlObj, SHFolder, ActiveX, Windows;
    
    function GetFolderLocation(Handle: HWnd; Folder: Integer): string;
    begin
      Result := '';
      SetLength(Result, MAX_PATH);
      if not Succeeded(SHGetFolderPath(Handle, Folder, 0, 0, PChar(Result))) then
          RaiseLastOSError();
    end;
    

    And finally, for those working with only Vista and higher, here's an example using SHGetKnownFolderPath - note this isn't available in pre-XE versions of Delphi (AFAIK-may be in 2009 or 2010), and you'll need to use KNOWNFOLDERID values instead of CSIDL_, like FOLDERID_LocalAppData:

    uses
      ShlObj, ActiveX, KnownFolders;
    
    // Tested on XE2, VCL forms application, Win32 target, on Win7 64-bit Pro
    function GetFolderLocation(const Folder: TGuid): string;
    var
      Buf: PWideChar;
    begin
      Result := '';
      if Succeeded(SHGetKnownFolderPath(Folder, 0, 0, Buf)) then
      begin
        Result := Buf;
        CoTaskMemFree(Buf);
      end
      else
        RaiseLastOSError();
    end;
    
    0 讨论(0)
  • 2021-01-22 09:38

    You should not write ini files to the program directory. Although it worked in the past, it has never been a good practice.

    You should be using %APPDATA% for user specific application data.

    You might want to read Best practices storing application data

    0 讨论(0)
提交回复
热议问题