David Maw
20-Nov-2005, 05:15 AM
Using the program directory as a default location to store error log files
typically only works if the user running the program is an administrator,
because they need the ability to write to that directory. Requiring users of
an application to be administrators is usually a bad thing.
Writing to the program directory can also cause trouble if multiple users
could be using it at the same time (as in a program on a network share). It
is probably better to store files in the user's local application data
directory:
I've attached a procedure to locate the directory; I use it with EurekaLog
by doing this:
CurrentEurekaLogOptions.OutputPath := GetAppdataDirectory;
When creating my main form.
It would be helpful to EurekaLog offered this capability as an option.
The code for GetAppdataDirectory in a sample command line program is below
for anyone who wants it.
David
mailto: dee gee em (3 letters) at surfcity dot net
================================================== ===================
program AppDirConsole;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
ShFolder;
function GetAppdataDirectory : string;
var SHGetFolderPath : TSHGetFolderPath;
hFolderDLL : THandle;
var
Buf: PChar;
begin
// Finds (or creates) a directory the user can use for Application state
storage
// Handles older operating systems which may be missing SHFolder.DLL
// Compiles and runs in either a GUI or a console application
Buf := StrAlloc(MAX_PATH);
hFolderDLL := LoadLibrary('SHFolder.dll');
try
SHGetFolderPath := nil;
if hFolderDLL <> 0 then
@SHGetFolderPath := GetProcAddress(hFolderDLL, 'SHGetFolderPathA');
if Assigned(SHGetFolderPath)
and (S_OK = SHGetFolderPath(0, CSIDL_APPDATA or CSIDL_FLAG_CREATE, 0,
0, Buf))
then
// This is the normal case, we got a path, just continue
else // Probably an ancient NT4 O/S with old IE, just use the temp
directory
GetTempPath(Max_path, Buf);
finally
if hFolderDLL <> 0 then
FreeLibrary(hFolderDLL);
result := Buf;
StrDispose(Buf);
end;
// Now append the name of the program itself
result := IncludeTrailingPathDelimiter(result)
+ ChangeFileExt(ExtractFileName(ParamStr(0)),'');
if not DirectoryExists(result) then
CreateDir(result);
end; // GetAppdataDirectory
begin
WriteLn(GetAppdataDirectory);
WriteLn('');
WriteLn('press enter to continue');
ReadLn;
end.
typically only works if the user running the program is an administrator,
because they need the ability to write to that directory. Requiring users of
an application to be administrators is usually a bad thing.
Writing to the program directory can also cause trouble if multiple users
could be using it at the same time (as in a program on a network share). It
is probably better to store files in the user's local application data
directory:
I've attached a procedure to locate the directory; I use it with EurekaLog
by doing this:
CurrentEurekaLogOptions.OutputPath := GetAppdataDirectory;
When creating my main form.
It would be helpful to EurekaLog offered this capability as an option.
The code for GetAppdataDirectory in a sample command line program is below
for anyone who wants it.
David
mailto: dee gee em (3 letters) at surfcity dot net
================================================== ===================
program AppDirConsole;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils,
ShFolder;
function GetAppdataDirectory : string;
var SHGetFolderPath : TSHGetFolderPath;
hFolderDLL : THandle;
var
Buf: PChar;
begin
// Finds (or creates) a directory the user can use for Application state
storage
// Handles older operating systems which may be missing SHFolder.DLL
// Compiles and runs in either a GUI or a console application
Buf := StrAlloc(MAX_PATH);
hFolderDLL := LoadLibrary('SHFolder.dll');
try
SHGetFolderPath := nil;
if hFolderDLL <> 0 then
@SHGetFolderPath := GetProcAddress(hFolderDLL, 'SHGetFolderPathA');
if Assigned(SHGetFolderPath)
and (S_OK = SHGetFolderPath(0, CSIDL_APPDATA or CSIDL_FLAG_CREATE, 0,
0, Buf))
then
// This is the normal case, we got a path, just continue
else // Probably an ancient NT4 O/S with old IE, just use the temp
directory
GetTempPath(Max_path, Buf);
finally
if hFolderDLL <> 0 then
FreeLibrary(hFolderDLL);
result := Buf;
StrDispose(Buf);
end;
// Now append the name of the program itself
result := IncludeTrailingPathDelimiter(result)
+ ChangeFileExt(ExtractFileName(ParamStr(0)),'');
if not DirectoryExists(result) then
CreateDir(result);
end; // GetAppdataDirectory
begin
WriteLn(GetAppdataDirectory);
WriteLn('');
WriteLn('press enter to continue');
ReadLn;
end.