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;
さまざまなまたは値の意味については、 MSDN のドキュメント ページを参照してください。値は似ていますが、Vista 以降でのみ使用でき、 SHGetKnownFolderIDList で使用されます。CSIDL_
FOLDERID_
FOLDERID_
サポートされていないというMS の警告を無視したくない方のために、推奨されるusingSHGetSpecialFolderPath
の代替バージョンを次に示します。GetFolderLocation
SHGetFolderPath
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;
そして最後に、Vista 以降のみを使用している場合は、SHGetKnownFolderPath を使用した例を次に示します。これは、Delphi の XE 以前のバージョンでは使用できないことに注意してください (AFAIK-2009 または 2010 の可能性があります) 。KNOWNFOLDERIDを使用する必要があります。の代わりにCSIDL_
値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;