Lazarus

Programming => Operating Systems => Windows => Topic started by: IPguy on March 18, 2012, 05:08:49 pm

Title: GetAppConfigDir question
Post by: IPguy on March 18, 2012, 05:08:49 pm
I'm using GetAppConfigDir(xx), which returns the following string (on a windows system):
xx = False: C:\Users\[username]\AppData\Local\PROGRM1
xx = True:  C:\ProgramData\PROGRM1

I would like to store the data in the following location:
C:\Users\[username]\AppData\Local\COMPANY1\PROGRM1
C:\ProgramData\COMPANY1\PROGRM1

I can deconstruct and rebuild that string to insert the company name, but I was wondering if there is a trivial way to insert the company name in that string for all target OS'?
Title: Re: GetAppConfigDir question
Post by: BlueIcaro on March 18, 2012, 06:56:48 pm
I did somethig like. I take the full path, remove the last word, it's easy found it, because is the name of your application.
May be something like this: (it's a code wrote on the fly, please check the correct works)
Code: Pascal  [Select][+][-]
  1. Dir := GetAppConfigDir(false);
  2. Pos := Pos (MyappName,Dir);
  3. Dir := Copy (Dir,0,Pos-1);
  4. Dir:= Dir+MyCompany+PathDelimiter\MyApp
  5. CreateFolder (Dir);
  6.  

/BlueIcaro


Then create a folder as you want, and store the that in a variable to use in your program.

/BlueIcaro
Title: Re: GetAppConfigDir question
Post by: Bart on March 18, 2012, 10:59:32 pm
Code: [Select]
function VendorName: String;
begin
  Result := 'MyCompany';
end;

function AppName: String;
begin
  Result:= 'MyAppName';
end;

....

begin
  ...
  OnGetVendorName := @VendorName;
  OnGetApplicationName := @AppName;
  Dir := GetAppConfigDir(false);
  //Dir should be something like: C:\Users\[username]\AppData\Local\MyCompany\MyAppName
end; 

Take a look at the code for GetAppConfigDir() function to seehow it works:

[code]
Function GetAppConfigDir(Global : Boolean) : String;
begin
  ...
    If (Result<>'') then
    begin
      if VendorName<>'' then
        Result:=IncludeTrailingPathDelimiter(Result+VendorName);
      Result:=IncludeTrailingPathDelimiter(Result+ApplicationName);
    end
  ...
end;

.....
Function VendorName : String;
begin
  If Assigned(OnGetVendorName) then
    Result:=OnGetVendorName()
  else
    Result:='';
end;

Function ApplicationName : String;
begin
  If Assigned(OnGetApplicationName) then
    Result:=OnGetApplicationName()
  else
    Result:=ChangeFileExt(ExtractFileName(Paramstr(0)),'');
end;


Here's afunction to get the root of GetAppConfigDir, so you can easily add 'MyCompany'MyAppName' without having to define the functions that act as OnGetApplication =Name and OnGetVendorName.
Code: [Select]
function GetAppConfigRoot(const Global: Boolean): String;
var
  OldGetAppName: TGetAppNameEvent;
  OldGetVendor: TGetVendorNameEvent;
begin
  OldGetAppName := OnGetApplicationName;
  OnGetApplicationName := @GetAppName;
  OldGetVendor := OnGetVendorName;
  OnGetVendorName := @GetVendor;
  try
    Result := GetAppConfigDir(Global);
  finally
    OnGetApplicationName := OldGetAppName;
    OnGetVendorName := OldGetVendor;
  end;
end;

Bart
Title: Re: GetAppConfigDir question
Post by: IPguy on March 19, 2012, 01:27:58 am
This is what I did prior to reading your responses.

Code: [Select]
  // gets the name of a dir in which the app should store its conf files on the current OS.
  // Also, see if the directory exists; if not, create it.
  // C:\Users\[UserName]\AppData\Local\Company\Project1\
  CfgDir  := GetAppConfigDir(False);   

  // Now, replace project name with Company name & verify it exists
  CfgDir := StringReplace(CfgDir, 'Project1', 'Company',[rfReplaceAll]);
  if not DirectoryExists(CfgDir)
    then CreateDir(CfgDir);

  // Now, append project name & verify it exists
  CfgDir := CfgDir + 'Project'+PathDelim;
  if not DirectoryExists(CfgDir)
    then CreateDir(CfgDir); 
Title: Re: GetAppConfigDir question
Post by: WackaMold on May 09, 2022, 06:50:39 pm
This part:
Code: Pascal  [Select][+][-]
  1. function AppName: String; // this callback function signature must match the default
  2. begin
  3.   Result := 'MyAppName';
  4. end;
  5.  
  6. begin
  7.   OnGetVendorName := @VendorName;
  8.  
requires:
Code: Pascal  [Select][+][-]
  1. {$LongStrings On} // strings are ANSI instead of short
The clue is in the compiler error on the assignment if strings are left as default / short:
Code: Pascal  [Select][+][-]
  1. Error: (4001) Incompatible types:
  2. got      "<address                 of function:ShortString;Register>"
  3. expected "<procedure variable type of function:AnsiString ;Register>"
TinyPortal © 2005-2018