Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Application's current directory


This question is answered.


Permlink Replies: 10 - Last Post: Nov 10, 2016 12:06 PM Last Post By: Garrett B
Garrett B

Posts: 77
Registered: 10/2/16
Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 4, 2016 5:13 PM
Hi

I am hoping someone can help me with the following:

My application looks for a .ini file at run time, and if it doesn't exist, it will create one.

The idea is to look for / create the file in the folder where the application is installed.

During development, I have been using the following code to know the application's folder:

   sApplication_Directory = IncludeTrailingPathDelimiter( ExtractFilePath( Application->ExeName ) );


This works when I am running the application from with the Embarcadero IDE.

However, when I deploy the application, the .exe is installed in the following folder:

   C:\Program Files (x86)\ProgName\ProgFolder


However, when I run this installed application, the call to the above code returns the following directory:
   C:\Users\me\AppData\Local\VirtualStore\\Program Files (x86)\ProgName\ProgFolder


So I can't get the application to look for the file at the correct location.

Question: Is there a way to know the install directory at run time?

Thanks

Garrett

Alex Belo

Posts: 626
Registered: 10/8/06
Re: Application's current directory
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 4, 2016 9:49 PM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:

However, when I deploy the application, the .exe is installed in the
following folder:

   C:\Program Files (x86)\ProgName\ProgFolder

Since Vista Program files is system-protected folder for security
reasons; application can not write into it without special privileges.

However, when I run this installed application, the call to the above
code returns the following directory:
   C:\Users\me\AppData\Local\VirtualStore\\Program Files
(x86)\ProgName\ProgFolder 


So I can't get the application to look for the file at the correct
location.

This is correct path for app's settings. See

Data and Settings Management
https://msdn.microsoft.com/en-us/library/ms995853.aspx

Store and retrieve settings and other app data
https://msdn.microsoft.com/en-us/windows/uwp/app-settings/store-and-retrieve-app-data

Google also returns a lot of refs on "msdn best practices storing
application specific data".

--
Alex
Garrett B

Posts: 77
Registered: 10/2/16
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 9:14 AM   in response to: Alex Belo in response to: Alex Belo
Hi Alex

Thanks for the reply.
I read through the documents, and decided to try using the Local App Settings, since all I want to read/write is a one line filename/string.
However, I don't know how to get the code to compile.
Could you have a look at the following please?

According to most of the docuemnts I came across, my C## code would look like this:

   Windows.Storage.ApplicationDataContainer localSettings =
      Windows.Storage.ApplicationData.Current.LocalSettings;


When I try and compile this, I get the error:

E2070 Invalid use of namespace 'Windows'


I tried to guess / include the required namespace, as follows:

using namespace Windows;


This is accepted, but I still get the same compiler error:

using namespace Windows::Storage;


This is not accepted. I get the following error:

E2316 'Storage' is not a member of 'Windows'
Alex Belo

Posts: 626
Registered: 10/8/06
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 9:56 AM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:

I read through the documents, and decided to try using the Local App
Settings
...
my C# code would look like this:
   Windows.Storage.ApplicationDataContainer localSettings =
      Windows.Storage.ApplicationData.Current.LocalSettings;

C++ is not C#. :-)

As described on

Data and Settings Management
https://msdn.microsoft.com/en-us/library/ms995853.aspx

SHGetFolderPath function
https://msdn.microsoft.com/ru-ru/library/windows/desktop/bb762181(v=vs.85).aspx

use

TCHAR szMyDocs[MAX_PATH];
BOOL r=SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, szMyDocs);

--
Alex
Garrett B

Posts: 77
Registered: 10/2/16
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 10:34 AM   in response to: Alex Belo in response to: Alex Belo
Thanks again for the response.
C++ is not C#. :-)

Sorry, that was a Monday mornign typo. I am currently working on a C++ project.

As described on

Data and Settings Management
https://msdn.microsoft.com/en-us/library/ms995853.aspx

SHGetFolderPath function
https://msdn.microsoft.com/ru-ru/library/windows/desktop/bb762181(v=vs.85).aspx

use

TCHAR szMyDocs[MAX_PATH];
BOOL r=SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, szMyDocs);

That above code works (thank you), and gives me:
C:\Users\me\AppData\Local


And I know I can append company name etc., on to this.

However:

1. My app is at:
C:\Users\me\AppData\Local\VirtualStore\Program Files (x86)\companyName\productName

And it doesn't seem right that I should have to manually append "\VirtualStore\Program Files (x86)" before appending company name and product name.

2. If I did manage to get following code to compile, which folder would it refer to?
  ApplicationDataContainer localSettings =
      ApplicationData.Current.LocalSettings;


Since all I want to do is save a few short string (a few filenames), it would seem preferable to me, if I could use the ApplicationDataContainer settings, because I could just read/write the settings (filenames) instead of searching through a file, and replacing text within the file.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Application's current directory
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 12:30 PM   in response to: Garrett B in response to: Garrett B
Garrett wrote:

That above code works (thank you), and gives me:

C:\Users\me\AppData\Local


And I know I can append company name etc., on to this.

That is the correct thing to do, yes.

However:

1. My app is at:

C:\Users\me\AppData\Local\VirtualStore\Program Files (x86)\companyName\productName

That is because you originally tried to write your file to "C:\Program Files
(x86)\companyName\productName", and "C:\Program Files (x86)" is protected
from being accessed by non-admins, so the OS silently redirected the write
to your user profile's VirtualStore rather than break your code. If you
try to load the file using the original "C:\Program Files (x86)\companyName\productName"
path, it will silently redirect to the VirtualStore again and find the file
if it is still there.

And it doesn't seem right that I should have to manually append
"\VirtualStore\Program Files (x86)" before appending company name
and product name.

NEVER manually build up a VirtualStore path. Let the OS redirect for you.

Since all I want to do is save a few short string (a few filenames),
it would seem preferable to me, if I could use the
ApplicationDataContainer settings, because I could just read/write the
settings (filenames) instead of searching through a file, and
replacing text within the file.

When saving a new file for the first time, use SHGetFolderPath(CSIDL_LOCAL_APPDATA)
(or SHGetKnownFolderID(FOLDERID_LocalAppData)) with your app's subfolder
appended to it (unless the user tells you differently).

When saving to an existing file, keep track of the path you loaded the
file from, so you can save changes to the same path (unless the user tells
you differently).

When loading an existing file, it is best to keep track of the file path,
such as in the Registry. But if you want to discover it dynamically, look
in CSIDL_LOCAL_APPDATA/FOLDERID_LocalAppData first, and if not found then
look in your app's installation folder (and let the OS redirect to the VirtualStore
if needed).

If you load a default file from your app's installation folder, you should
save any changes to the user's profile instead. NEVER write files to your
app's installation folder (only your app's installer should ever do that).

--
Remy Lebeau (TeamB)
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 12:15 PM   in response to: Garrett B in response to: Garrett B
Garrett wrote:

However, I don't know how to get the code to compile.

You can't use WinRT APIs in C++Builder projects. To determine the path of
special OS folders, use the Win32 API SHGetFolderPath() or SHGetKnownFolderPath()
functions:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181.aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/bb762188.aspx

--
Remy Lebeau (TeamB)
Garrett B

Posts: 77
Registered: 10/2/16
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 10, 2016 9:42 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks for the reply Remy.

It was very clear :)

So I am using SHGetFolderPath(CSIDL_LOCAL_APPDATA), and all my problems have gone away.

Before we close off this thread, can you tell me how/when an application's local app folder is normally created?

My installer file creates a directory in C:\Program Files (x86)\CompanyName\ProductName, and it dutifully removes itscontents and this folder when the application is uninstalled.
This is the NSIS installer, and to determine the location of the program files directory, it uses the $PROGRAMFILES constant/identifier.

I am able to get my application to manually create a folder in the Local App Folder at runtime (C:\Users\me\AppData\Local\CompanyName\ProductName), but this doesn't seem right at all, as there would be no way to remove this folder when the app is uninstalled.

I am sure that it is the installer that should have the responsibility of creating and removing this directory.

First question:

- Am I right? Is it the installer that should create this directory?

Second question: ( I apologise for appending this question here, as it should probably have its own thread elsewhere, but it seems to round out this thread, and I have searched for an hour for the answer: )

- Within the application I use SHGetFolderPath(CSIDL_LOCAL_APPDATA) to determine the local app directory. However, I don't know how I should determine this directory at install time. Have you any pointers to this? As I say, I have been searching for this information, but in vain.

Kind regards

Garrett

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 10, 2016 10:55 AM   in response to: Garrett B in response to: Garrett B
Garrett wrote:

Before we close off this thread, can you tell me how/when an
application's local app folder is normally created?

That is up to you to decide based on your own needs. You could have your
installer create it before the app is run for the first time. Or you can
have the app create it the first time it is needed. Does not really matter
either way.

I am able to get my application to manually create a folder in the
Local App Folder at runtime
(C:\Users\me\AppData\Local\CompanyName\ProductName), but this
doesn't seem right at all, as there would be no way to remove this
folder when the app is uninstalled.

You can have your uninstaller remove that folder if it exists. Just because
the installer may not create the folder does not mean the uninstaller cannot
remove it.

- Within the application I use SHGetFolderPath(CSIDL_LOCAL_APPDATA)
to determine the local app directory.

Note that it will find the AppData folder for the user that is running your
app, unless you specify otherwise.

However, I don't know how I should determine this directory at install
time.

That is a bit tricker to handle, since the installer will likely be running
as an elevated admin, not the user who will be running the app after installation.
If you need to create a per-user folder, but the installer is running as
a different user, the installer will have to impersonate the intended user
and pass that user's token to SHGetFolderPath(). Check your installer's
documentation, it likely has functionality available to account for this.

--
Remy Lebeau (TeamB)
Garrett B

Posts: 77
Registered: 10/2/16
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 10, 2016 12:06 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thanks Remy

That's enough info for me at this stage.

Regards

Garrett
Anton Kecherk

Posts: 6
Registered: 12/7/16
Re: Application's current directory  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 7, 2016 1:02 AM   in response to: Garrett B in response to: Garrett B
Garrett B wrote:
Hi

I am hoping someone can help me with the following:

My application looks for a .ini file at run time, and if it doesn't exist, it will create one.

The idea is to look for / create the file in the folder where the application is installed.

During development, I have been using the following code to know the application's folder:

   sApplication_Directory = IncludeTrailingPathDelimiter( ExtractFilePath( Application->ExeName ) );


This works when I am running the application from with the Embarcadero IDE.

However, when I deploy the application, the .exe is installed in the following folder:

   C:\Program Files (x86)\ProgName\ProgFolder


However, when I run this installed application, the call to the above code returns the following directory:
   C:\Users\me\AppData\Local\VirtualStore\\Program Files (x86)\ProgName\ProgFolder


So I can't get the application to look for the file at the correct location.

Question: Is there a way to know the install directory at run time?

Thanks

Garrett


Wonder, between use this file as application.ini in your applications config folder. Uncomment
and set all options that your application needs. Alternatively use this file
as a cheatsheet and copy all needed options to your application.ini.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02