A hidden settings file specific to an instance of an executable at a given path - c#

Not sure I have the best title for this question. Feel free to modify it or suggest a change and I will do the edit myself.
I have a standalone executable which wants to maintain a settings.bin file specific to the application. There are two obvious ways to do it:
1. Create/Read the file from the local directory where the executable resides
Positive: User can copy the exe and bin file to multiple directories and have multiple versions with different settings.bin files.
Negative: I don't want to polute executable directory.
2. Create/Read the file from a "hidden" location like the Local Application Data folder.
Positive: Not poluting the executable directory.
Negative: The settings.bin file will be shared amoungst any instance
of the executable regardless of where it is locaed.
I don't want to do either of these solutions because neither meet both of my requirements, which are:
Don't polute the executable directory (IE: don't create a local file).
The settings.bin file is different based on the location of the executable.
Any thoughts? I wanted to embed the settings.bin file as a resource but quickly learned you can't write to an embedded resource. I'm all out of ideas.

Use option 2 with a small modification that cancels your negative point (not shared)
You must have something that you can differentiate between exe files.
If all reside in different paths I would do the following:
1) Hash the location of the executable (md5 of the path)
2) Create a directory in the appdata with the hash
3) Store my files there
Else I would try to enumerate myself compared to other processes:
1) When starting check the app data.
2) Attempt to lock a file for writing at:[App Data]\1\sem.oi
3) If that failed attempt to lock a file for writing at:[App Data]\2\sem.oi
Use the settings in the directory that you were able to open the file in
Hope this helps.

Well, you can define your configuration data into the application resource file like a sequence key-value pairs. In this way that information will be embeded into the your binary file, so hopefully you will meet the both of your requeirements.
no file created specially for configuration
and every file can have it's own built-in configuration, which means you have to made different builds in this case.
What about do not creating a file, but having a flexible configuration on local machine based on the exe path, I think it's hardly possible, if not via some network acess, and some bizzar (in my opinion) architecture.
If you would explain why you have these kind of requirements, may be can give more suitable answer, in case if it's not as is now.

Related

where is the correct location for Data folder in developing process C# deskTop app

i write desktop app in C# .... this app will auto generate an C/C++ code for an embededd system project
so i have to copy some pre_writen drivers to the target folder (where the file is generated)
the problem is i don't know where i can correctly put the sourc driver in !!
for now i put the source driver in in the project foldr and i refrance it in my code lik
// projectfolder\bin\Debug\netcoreapp3.1\file.exe
string path = (Assembly.GetExecutingAssembly().Location);
DirectoryInfo exeDir = new DirectoryInfo(path);
DirectoryInfo projectDir = exeDir.Parent.Parent.Parent.Parent;
// now i can get the driver foler like this
string DriverPath = Path.Combine(projectDir.fullName,"drivers");
i guss that folder in the product level will be in C:\ProgramData
but for developing where the location shoud be in ?
In Windows there are different types of data that may be consumed by an Application such as
Application Properties
Application settings enable you to store application information dynamically. Settings allow you to store information on the client computer that should not be included in the application code.
Ex: Position, Font, Styles, User Configuration
File Type: App.Config(Is created at design time and is by default put into BIN folder) and User.Config (Created at run time)
Project > Add New Item > Installed > Visual C# Items > Application Configuration File
Application Data
Contains all the data, settings, and user files that are required by the installed software and UWP apps. These are user agnostic data.
Ex: Images, Resources, Sprites, Data Templates, txt files. It may also contain App.Config files
File Location: C:\ProgramData Environment.SpecialFolder.CommonAppData
User Data
Contain all data that is user specifc, such as his/her app specific settings.
Ex: Any type of data
File Location: C:\Users\[USERNAME]\AppData\Roaming Environment.SpecialFolder.AppData or Environment.SpecialFolder.MyDocuments
i guss that folder in the product level will be in C:\ProgramData but
for developing where the location shoud be in ?
yes, it will go to ProgramData, but during the development you can have it in your BIN folder or a directory of your choice if it matters
However most of the above will come into picture when you package your App to an MSI and bundle in all the dependency files and where they need to go.
EDIT
Based on the OPs clarification in comments, .CPP files will automatically go into the BIN/Debug Folder of your C# app.
You will need to dynamically place your device drives in the directory where your exe is running
To access the directory where your app is running :
string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location
Output of Path = Absolute path where your exe is running
C:\Users\User1\source\repos\Test\Test\bin\Debug\Test.exe
string exeDirectory = Path.GetDirectoryName(exePath);
The Directory path where your exe is situated
C:\Users\User1\source\repos\Test\Test\bin\Debug
The default location in a c# dekstop app in Environment.CurrentDirectory + "\\Folder"
This is mostly a question of how often the data will change. And how that will interact with the very strict management of write rights since NTFS became common (While the rule predates NTFS, with mostly FAT - and thus no rights to stop us - few programmers cared).
You can and even should put stuff into the Programm directory itself, if it does not change outside of Programm Updates/Reinstallations. If it only changes with a Installer or Updater - things that need administrative rights for their work anyway - it belong there.
If changes happen more often then that - especially stuff that can change at runtime or even needs to change at runtime - where the programm folder becomes unuseable. In this case the programm directory should at tops include a template file. Something you can copy to the real directory as a baseline, to have something to start working with. As for where to put this changeable data, look at the SpecialFolders Enumeration. The Userprofile - particulary Appdata folders are the point to look at. Wich specific one to use is a question of how you want it to interact with Domain Controler Synchronisation (Roaming vs non-Roaming user). Or if you want it to end up in Common.
Drivers sound like that rare case, where the programm directory is entirely fitting. Optionally you could have the drivers installed as a parallel application. Something that can be managed/updated seperately and is simply a requirement for your programm. Something that might be shared across multiple applications.

Building own Installer for Game

I have made a game and wish to distribute it online. I have spent years playing around with many Installers (InstallWise, InstallShield, etc, etc, etc).
They are very complex, require time and in most cases, a decent amount of money. So I want to write my own Installer, that will install my game for the user.
My game is comprised of:
DLL files (these will go inside the Game's folder, inside Program Files.
The application file itself (a single .exe file).
I will also need to create a shortcut on the Desktop (if the user allows) which will launch the .exe in Program Files folder. I can already do this.
I know how to copy and write files to folders. What I am asking is, how do I "pack" the files into my installer file, so that I can give a user a single file to download, which will then "unpack" the game's files into the appropriate location?
I have asked this question 2 years ago on SO and was met with hostility; the person claimed that this is not possible - but incase they haven't noticed, 90% of installers are just a single file, which unpacks its contents into a directory/several directories. So I know it is possible.
The only way I can think of that I can get this to work is by going over each file that needs to be packed, and reading the bytes into the app and storing it into an embedded file. And when the app is run, it will look for embedded files/bytes and write those bytes to new files in the specified locations. Please correct me if I am wrong.
Any help will be greatly appreciated.
You will need to either save the bytes in your installer, which means that you will need a builder for the actual installer which will use CodeDom.
Or you can download the files from a server, which seems faster in this case.
You choose.
To do so i would use a Self-Extract Zip. this is an exe that will unpack itself with all necessary files then you set the after extract command to call and exe of yours which copy everything where you want and then create yourself link on desktop and such. not very difficult.
In the Self-Extract file you can also specify that the content is extracted in the temp folder of the computer allowing you to find stuff using environment special directory

defining location of files at deployment time

I have an app that has search functionality. The search algorithm is compiled to a separate dll. In the C# code for the search algorithm, I am using strings held in a settings file to point to the directory where the search index resides. But once the search code is compiled, the settings file is somehow incorporated in the dll. I want to have multiple versions of this code running on my server with each pointing to a different location for the index. And I want the operator to change a file to have each version point to something else as they find necessary. Both config files and settings files end up getting incorporated in the dll. How do I then accomplish this? What is the right industry standard way of doing this?
It's strange that the settings file is compiled... are you sure about that? Setting, config and resx files should be copied to the output directory, it's even a property you can modify on solution explorer. Then you should get it's values by doing
System.Configuration.ConfigurationManager.AppSettings.Get("YourKey")
But I think this won't know about user changes until app is restarted. If you want settings to be dynamic you should either store them on a database, or on a file that you open, read and close every time you need it.
Hope this helped!

Using WritePrivateProfileString to write path issue

I am using WritePrivateProfileString in c# (through DllImport) to store paths taken from textboxes on the interface. And the .ini file name is hardcoded in my application
string ini_file = ".\\config.ini";
However, when the file writing happens, the configuration file is written to the first path taken from the interface instead of writing it to the exe directory. Which is quite odd.
Debugging shows that the values are sent correctly to the WritePrivateProfileString but it still is written to the wrong location. Anyone knows why is that happenening?
I'd guess that something is changing the working directory of your process, most likely your code in the process. Note that the documentation has this to say:
If the lpFileName parameter does not contain a full path and file name for the file, WritePrivateProfileString searches the Windows directory for the file. If the file does not exist, this function creates the file in the Windows directory.
Now my guess is that this applies if you supply just a file name. Because your file name starts with . I believe that will force the function to start from the current working directory.
Having said all of that, and no matter what the cause of the problem is, you should use a fully-qualified path in order to make sure the file is written where you want it to be written. Whenever you want the file to go in a specific directory, it's always easiest to force that by using fully-qualified paths.
You can find the path to your executable using Application.ExecutablePath and then remove the file name part.
Another point to make is that the same directory as the executable may be a bad choice. If your program is installed under the Program Files directory then the directory which contains the executable will not be generally writeable. I think you should consider using a directory under in the user profile. Look for one of the Environment.SpecialFolder values.
Further to David Heffernan's answer - you can use
Path.GetDirectoryName(Application.ExecutablePath);
to safely get just the running application's folder part.
If you're in a dll rather than an executable, you can use
Path.GetDirectoryName(Assembly.GetAssembly(typeof(MyClass)).CodeBase);
Both require System.IO, and were originally posted here. Second example also requires System.Reflection).
Application data files are supposed to be written to the LocalApplicationData special folder.
string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
You typically will not have permissions to write into the Program Files folder etc.

C# -> Updating an AppSettings.config file on Win7/Vista

I can't see anything on here but I do remember being told that If you want an application to update a config file then it needs to be under ...
**C:\Users\Ibrar Mumtaz\AppData**
Well somewhere there, the reason being is that the user should have permisions to update a config file here and not under the applications install folder. This is the impression that I am under and I'm fairly certain that this is definately the case. As I think I read that on here = p
My question is, is there anybody on here that can shine some light on this as this is the last feature I want to implement before I give my application out to test.
1) First thing is, an installer is needed to set up the folder and then drop my apps config file into it. I already am using the visial studio installer so I have my app packaged up but this point is throwing me off? How do I do this then? I just need someone to show how to do this and I should be O.K reconfiguring my app to look for the new home of the config file.
2) I should be able to work out how to find the folder and locate the config file found within it. As once I know the installer is chucking the config file out into the right folder where the user has permissions then it should be straight forward from there.
Thanks for reading.
UPDATE:
It was pretty straight foward, as the VS Installer has an option to add a special folder so all that was left was to access the folder programmatically and read and write to the config file. ONE PROBLEM? The ConfigurationManager class which I have used to create my config file for my application expects my config file to be local to the application and not miles away in a completey different part of the local FileSystem? Errr help here Plz?
Ibrar
If you are using the VS Settings file to create application setting keys, and have values that the user might want to change in runtime, and save his preferences, just set the scope of those settings to "User" instead of "Application".
That way you will have a setter method for them, and you can edit the Settings.Default instance, and when you are done call the Save() method to persist them to disk.
The file will be saved in the user's "AppData" folder, wherever it is, under some cryptic folder. But you needn't worry about it's location most of the time, since it will be read automatically on the next execute, and persisted to the same location on subsequent runs.
Afaik the installer can be extended with classes that do things.
On INSTALL-action to do could be to
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"My app name");
if (!Directory.Exists(path)) Directory.CreateDirectory(path);
And vice-versa on uninstall.
App.config files are related to where the physical assembly is located I think.
Actually, if your app is running on the user's machine- it will have whatever permissions that user has. So most likely, you can expect to be able to write anywhere on the file system.
However it is possible the user would be running under a restricted acct, and thus not have the permissions. So you could just use the registry to store where your config file is (install folder), then when you try to update it, if it fails for permissions, ask the user to grant it.
Or you could use the Windows standard folders, as you were getting at, because doing so also separates out user data from application data.
Use the Environment.GetFolderPath () method to get the 'special folder' paths in your app.
http://www.programmersheaven.com/2/Les_CSharp_15_p2
http://msdn.microsoft.com/en-us/library/14tx8hby.aspx
If you are talking about application settings found on project Properties -> Settings tab, then there're two different types of settings: user-level and application-level.
If you need to change any settings in run-time, these would be user-level settings (http://msdn.microsoft.com/en-us/library/cftf714c.aspx) and all changes would be buried somewhere in the private folder in your user profile.
If you want to update application-level settings, your best shot would be to do that during software installation. In this case you don't need to look for the configuration file (YourApp.exe.config) anywhere but in the application folder. More likely you would need to create some sort of post-install event handler in your setup package and run some script or another application which would update data in YourApp.exe.config. Everything in the setup package will be executed with elevated priviledges and thus that configuration file would be writeable. BTW, this scenario applies to 2000 and XP, if the user is using limited user account type priviledges.
Because I did not technically find the answer I was looking for, after 6 months I have come back to my application and have managed to produce a solution that does not break my current architecture.
If you are implementing an application to make use of some of the features on offer by the ConfigurationManager then it offers a static method called:
ConfigurationManager.OpenMappedExeConfiguration(); // takes two arguements.
It can be used like this:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = returnUsersAppDataFolderPath();
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
e.g
fileMap.ExeConfigFileName = #"some file path external to your applications install folder."
remember to use '#' symbol in front to allow the compiler to literally treat the string on as is basis.
If the config file can be conveniently locally located then just use the:
ConfigurationManager.OpenExeConfiguration(string exePath)
Above is what you would typically use but for me i needed my config file to located under the users AppData folder so the first option is what I needed. And it does indeed work.
I hope this helps others as it does for me as I want to deploy my application to Win7 and vista environments therefore this question needed asking if I was to stick to using the ConfigurationManager it's a shame the method of choice in the end never really stood out in the first place = ).
If you want to read from your config file then leave a comment and I will show you how I managed to do that also.

Categories