Recent

Author Topic: XMLPropStorage, use GetAppConfigDir? (SOLVED)  (Read 5905 times)

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
XMLPropStorage, use GetAppConfigDir? (SOLVED)
« on: December 30, 2017, 05:52:01 pm »
Is it possible to force XMLPropStorage object to use

GetAppConfigDir(false)+'config.xml'

as FileName parameter? I've tried typing in

GetAppConfigDir(false)+'config.xml'

(in the Object Inspector) but result (on windows 7) is not what I wanted.

Kind regards,
Michael
« Last Edit: January 01, 2018, 08:08:18 pm by mijen67 »

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #1 on: December 30, 2017, 07:55:02 pm »
Are you trying to input that string in the Object Inspector during a design time? It wont work, you need set it during your application run time.

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #2 on: December 30, 2017, 08:17:51 pm »
Are you trying to input that string in the Object Inspector during a design time? It wont work, you need set it during your application run time.

I understand it must be run time, because path is different for each user, OS versions and for different platforms.

However, can it be done, run time?

Basically I want to follow the simplest approach from
http://wiki.lazarus.freepascal.org/Remember_form_position_and_size and save Form1 properties Left, Top, Width, Height by using the TXMLPropStorage component.

Unfortunately by default it saves the .xml files in the application folder and that is not the MS way (is it allowed on Mac's? Linux? ). Is it good practice?

I want to keep things simple, and maybe I should just accept that it is the Lazarus way? And let the installer install the application in another folder than C:\Program Files\ ?  Or what would you recommend?

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #3 on: December 30, 2017, 09:03:30 pm »
but result (on windows 7) is not what I wanted.

And let the installer install the application in another folder than C:\Program Files\ ?  Or what would you recommend?
Perhaps you would want to read up with this article.

Although a different installation path is allowed, it is not by default that when a user choses to install your application to another location that your program is allowed to read from and/or write to that same directory location.

Your application has no way of knowing how a system of a user is configured so the only advise is to use the default directories that the OS intended for your application to be used. You might not like it, but if you go against that then your application will simply not run.

The days of fat32 and users that provide themselves admin rights is far gone. Any application that tries to convince me that it requires admin rights to be able to install itself goes to directly to the trashcan (there are some exceptions to that rule but such software does other things then just being some end-user application). Even Lazarus installer can "go fish" for me.

That is why GetAppConfigDir was implemented: to obey the OS rules as much as possible (and when possible). The result of GetAppConfigDir can somewhat be altered as written in its documentation.

jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #4 on: December 30, 2017, 09:10:25 pm »
The GetAppConfigDir works because I use it and Windows returns the USER folder for
data.
 
 Place break points on the line and examine the content of the output..

 If the FileName in the XML is showing the correct path, then maybe there is something
wrong ?
The only true wisdom is knowing you know nothing

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #5 on: December 30, 2017, 09:16:59 pm »
Any application that tries to convince me that it requires admin rights to be able to install itself goes to directly to the trashcan (there are some exceptions to that rule but such software does other things then just being some end-user application). Even Lazarus installer can "go fish" for me.

I agree. So your advice is? Not to use TXMLPropStorage? Or can I change it's FileName parameter run-time, so that I can get to use %appdata% instead?


jamie

  • Hero Member
  • *****
  • Posts: 6091
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #6 on: December 30, 2017, 09:21:00 pm »
My point is, that function does work, I use it and it returns a string of the USER folder..

you need to conduct some test to verify the contents of this string to ensure it is in fact
returning you a valid string at runtime ..

 I use the Caption property as a test bug display

 Caption := GetAppConfigDir(False)+yourFilename

 if that passes, then assign it to the filename of the component..
then read it back again, displaying it to the forms Caption to make sure it remained that
way..
 if the file still insist on saving to the EXE folder then there is an issue with that component.

I use TIniFile component for basic settings it works.


The only true wisdom is knowing you know nothing

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #7 on: December 30, 2017, 09:22:27 pm »
So your advice is? Not to use TXMLPropStorage?
You can use TXMLPropStorage, just require to change the default location.

Quote
Or can I change it's FileName parameter run-time, so that I can get to use %appdata% instead?
GetAppConfigDir should (on windows at least) return the correct path where your application is allowed to store data.

You still havent' told us what GetAppConfigDir returned for you, so at this point in time i am unable to determine if there perhaps might be something amiss. AS user jamie wrote: it works for me tm

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #8 on: December 30, 2017, 09:25:35 pm »
The GetAppConfigDir works because I use it and Windows returns the USER folder for
data.
 
 Place break points on the line and examine the content of the output..

 If the FileName in the XML is showing the correct path, then maybe there is something
wrong ?

I'm not questioning GetAppConfigDir. It does work.

I'm asking how to let XMLPropStorage object use it for finding path to .xml configuration file? I guess there is some timing involved. I cannot just set XMLPropStorage1.FileName := ...  anywhere in my project?


molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #9 on: December 30, 2017, 09:32:05 pm »
ah, in that case my apologies mijen67. I simply misunderstood your 'problem'.

I'll try to dig up some of my old code, as i don't recall from memory if there is/was a particular order in which events should take place.

It goes without saying that you can actually 'use' the component after the correct filename was set, as properties are read automatically from the config-file. So yes, order of things do matter.

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #10 on: December 30, 2017, 09:38:04 pm »
ah, in that case my apologies mijen67. I simply misunderstood your 'problem'.

I'll try to dig up some of my old code, as i don't recall from memory if there is/was a particular order in which events should take place.

It goes without saying that you can actually 'use' the component after the correct filename was set, as properties are read automatically from the config-file. So yes, order of things do matter.

No problem, I definitely should have been more specific. Looking forward to seeing the proposal!

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #11 on: December 30, 2017, 09:44:58 pm »
While my search is running, i realized something that could perhaps influence your results. GetAppConfigDir is able to return a path that doesn't already exist and that _might_ perhaps not be handled correctly by TXMLPropStorage . In that case the directory has to be created manually (forcedirectories comes to mind).

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #12 on: December 30, 2017, 10:41:37 pm »
Funny thing is that in the example i'm quoting from i forced to use Application.exename and changing extension to xml  :-[

(i changed it to force it to use another path).

It shows the basic usage. It is some silly buttons and labels that get stored, restored and changed (not important unless you wish to know more, just say so and i post complete project).
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   ExtCtrls, XMLPropStorage;
  10.  
  11. type
  12.  
  13.   { TForm1 }
  14.  
  15.   TForm1 = class(TForm)
  16.     Button1: TButton;
  17.     Button2: TButton;
  18.     XButton1: TButton;
  19.     XButton2: TButton;
  20.     XButton3: TButton;
  21.     XButton4: TButton;
  22.     Button3: TButton;
  23.     XLabel1: TLabel;
  24.     XLabel2: TLabel;
  25.     XLabel3: TLabel;
  26.     XLabel4: TLabel;
  27.     Panel1: TPanel;
  28.     XMLPropStorage1: TXMLPropStorage;
  29.     procedure Button1Click(Sender: TObject);
  30.     procedure Button2Click(Sender: TObject);
  31.     procedure Button3Click(Sender: TObject);
  32.     procedure FormCreate(Sender: TObject);
  33.     procedure XMLPropStorage1RestoreProperties(Sender: TObject);
  34.   private
  35.     { private declarations }
  36.   public
  37.     { public declarations }
  38.   end;
  39.  
  40. var
  41.   Form1: TForm1;
  42.  
  43. implementation
  44.  
  45. {$R *.lfm}
  46.  
  47. { TForm1 }
  48.  
  49.  
  50. procedure TForm1.Button1Click(Sender: TObject);
  51. begin
  52.   // SaveSettings
  53.   XMLPropStorage1.Save;
  54.   Button1.Enabled := False;
  55.   Button2.Enabled := True;
  56. end;
  57.  
  58. procedure TForm1.Button2Click(Sender: TObject);
  59. begin
  60.   Button2.Enabled := False;
  61.   Button3.Enabled := True;
  62.  
  63.   // Simulate action
  64.   XButton1.Hide;
  65.   XButton2.Hide;
  66.   XButton3.Hide;
  67.   XButton4.Hide;
  68.  
  69.   XButton1.Caption := 'This is button 1';
  70.  
  71.   XLabel1.Caption := 'changed';
  72.   XLabel2.Color:= clRed;
  73.   XLabel1.Caption := 'changed';
  74.   XLabel2.Color:= clGreen;
  75. end;
  76.  
  77. procedure TForm1.Button3Click(Sender: TObject);
  78. begin
  79.   // LoadSettings
  80.   XMLPropStorage1.Restore;
  81.   Button2.Enabled := True;
  82. end;
  83.  
  84. procedure TForm1.FormCreate(Sender: TObject);
  85. begin
  86.   XMLPropStorage1.FileName := 'G:\Temp\SomeFileStorage.xml';
  87.   // initialize 'action' buttons
  88.   Button1.Enabled := True;
  89.   Button2.Enabled := False;
  90.   Button3.Enabled := False;
  91. end;
  92.  
  93. end.
  94.  

That worked for me and should work the way you want to, by changing:
Code: [Select]
  XMLPropStorage1.FileName := 'G:\Temp\SomeFileStorage.xml';
into
Code: [Select]
  XMLPropStorage1.FileName := GetAppConfigDir(False)+'SomeFileName';

As said in my previous post, make sure that the path that GetAppConfigDir returns actually exist.

In case you still have issues then please describe them and also state lazarus and fpc version that you are using.

mijen67

  • Full Member
  • ***
  • Posts: 130
  • It's hard to beat the bandwidth of a flying DVD
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #13 on: January 01, 2018, 03:49:11 pm »
That worked for me and should work the way you want to, by changing:
Code: [Select]
  XMLPropStorage1.FileName := 'G:\Temp\SomeFileStorage.xml';
into
Code: [Select]
  XMLPropStorage1.FileName := GetAppConfigDir(False)+'SomeFileName';

As said in my previous post, make sure that the path that GetAppConfigDir returns actually exist.

In case you still have issues then please describe them and also state lazarus and fpc version that you are using.

Perfect, thanks!

I added an initialization section to the main unit with the following contents:

Code: Pascal  [Select][+][-]
  1. fileConfigPath:=GetAppConfigDir(False);
  2. IncludeTrailingPathDelimiter(fileConfigPath);
  3. ForceDirectories(fileConfigPath);

When a form has an XMLPropStorage component, I can just add:

Code: Pascal  [Select][+][-]
  1. XMLPropStorage1.FileName:=fileConfigPath+Self.Name+'.xml';

to each .FormCreate method.

Now it is working, and the program is saving data in a valid location.

How do I mark the thread "solved"?
« Last Edit: January 03, 2018, 10:56:57 am by mijen67 »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: XMLPropStorage, use GetAppConfigDir?
« Reply #14 on: January 01, 2018, 04:13:41 pm »
Perfect, thanks!
You're welcome and glad that it worked for you :)

Indeed you can also use your initialization section to setup some things like you did.

Perhaps as a small tip: I personally prefer to use a TDataModule (that gets created before the first/main form) that has such features nicely tucked away as that allows these implementations to be easily re-used for other projects). But an additional (non visual) unit that has some global procedures/functions and/or initialization section works just as well.

As long as it works for you then you should be good to go no matte what you use. :)

Quote
How do I mark the thread "solved"?
Unfortunately (and in 2018) the forum software does not seem to have a standard solution integrated for marking a thread as solved.

In case you are the starter of the thread, then you can edit your first post and insert [SOLVED] before the original topic title. Of course you would have to (re)post that message as well for the changes to take effect.

Happy Coding !
« Last Edit: January 01, 2018, 04:17:10 pm by molly »

 

TinyPortal © 2005-2018