我的应用程序是在delphi中构建的,除了Windows 7 64位机器外,它在其他平台上运行完美。每次尝试关闭应用程序都会给我这个错误 “无法写入应用程序file.ini'
这是我关闭的代码
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
frmMain.close;
end;
答案 0 :(得分:9)
此错误通常是由于尝试写入Program Files
下的应用程序自己的文件夹而导致的,这不适用于Vista及更高版本下的非管理员(如果您不是以管理员身份运行,则不允许使用XP)或高级用户)。
以下是获取.INI文件的正确文件夹的一些代码:
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;
我在我的应用程序中使用这些来检索非漫游配置文件文件夹,并使用在其下创建的子文件夹作为我的应用程序的数据。它是在创建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;
有关各种CSIDL_
或FOLDERID_
值的含义,请参阅MSDN's documentation page。 FOLDERID_
值类似,但仅在Vista及更高版本上可用,并与SHGetKnownFolderIDList一起使用。
对于那些不愿意忽视MS关于SHGetSpecialFolderPath
不受支持的警告的人,这里是使用GetFolderLocation
的{{1}}的替代版本,这是首选:
SHGetFolderPath
最后,对于那些只使用Vista及更高版本的用户,这里有一个使用SHGetKnownFolderPath的例子 - 注意这在Delphi的前XE版本中是不可用的(AFAIK可能在2009年或2010年),并且您需要使用KNOWNFOLDERID值代替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;
,例如CSIDL_
:
FOLDERID_LocalAppData
答案 1 :(得分:4)
您不应将ini文件写入程序目录。虽然它过去工作,但它从来都不是一个好习惯。
您应该将%APPDATA%
用于特定于用户的应用程序数据。