I have a very strange problem with my WPF application. I am trying to open a regular config file using this method:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = ConfigurationManager.AppSettings[ PATH_TO_CONFIG ]; //which returns a valid path
s_config = ConfigurationManager.OpenMappedExeConfiguration( fileMap, ConfigurationUserLevel.None );
This works fine when you first run the application - it finds the config file in the directory the app .exe resides. - D:\MyApp\bin\Debug\MyConfigFile.conf But when you open another instance of the application by right-clicking on the running application icon in the toolbar, and from the context menu you choose to open new instance then I get a strange behaviour:
The s_config.FilePath now doesn't find my config file, because it is pointing to "C:\Windows\systems32\myConfigFile.exe.config" And this problem only reproduces when the second application is started like this.
Does anybody has an idea what might be the problem?
We didn't find the solution to the problem so we worked around it. In case the config file is not found, we used
System.Reflection.Assembly.GetExecutingAssembly().Location
to get the full path to the config file and to pass is to fileMap.ExeConfigFilename
Related
I have some Selenium C# tests hosted on Azure which they need to look for the pre-built excel file in project tree, stored inside bin folder, to execute some file upload validation scenarios.
When they are executed locally these scenarios pass without any problem, but when it comes to be executed on the Azure they receive the following error.
invalid argument: File not found : D:\a\r1\a_Selenium_Tests\TestApplication\bin\Debug\netcoreapp3.1\Files\SC003_CT014_ActiveEmployees.xlsx
The files do exists in the following path: ...\bin\Debug\netcoreapp3.1\Files...
And the code I use to them is:
string root = Directory.GetCurrentDirectory() + "\\Files\\" + file;
Do you know if there's a missing file configuration or building the filePath in another way?
Thanks for your help :D
Directory.GetCurrentDirection() returns the current working directory, not the folder in which the DLL file resides. The current working directory is a different thing. In your case, the current working directory is probably something like D:\a\r1\. Instead, you need to get the folder in which the test assembly resides:
var binDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
// ^^^^^^^^^
var excelFilePath = Path.Combine(binDirectory, "Files", "SC003_CT014_ActiveEmployees.xlsx");
Note: Replace GetType() with typeof(ClassName) if you are executing your code from a static method, or you would like to specify a path to a different assembly than the one that is currently executing.
The documentation for ConfigurationManager.OpenExeConfiguration(string exePath) states:
Opens the specified client configuration file as a Configuration
object.
It also states that exePath is "The path of the executable (exe) file"
The method is supposed to open the *.exe.config file for the executable at the path specified by exePath, and that a ConfigurationErrorsException will be thrown if "A configuration file could not be loaded.".
The following code uses the path of a non-executable and the directory of that path contains no *.exe.config files. Yet the code executes without any exceptions, nor any other sign of an invalid argument.
var configs = Directory.GetFiles("C:\\NoConfig", "*.config");
Debug.Assert(configs.Length == 0);
File.WriteAllText("C:\\NoConfig\\notes.txt", "This is not an executable, and there is no .config file in its folder.");
var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt");
Debug.Assert(config != null);
Yet it will now slowly become deprecated for the new .NET Core JSON based configuration, and will not be reviewed or fixed anyway.
So, is this due to a bug in this overload of the OpenExeConfiguration method?
I just wanted a 2nd, and nth opinion before I raised it on MS Connect. And Connect is down at the moment.
ADDED: If I call OpenExeConfiguration with a valid exePath, to a real executable (tested), with a valid .config file, then it reads but does not parse the file. I have to request the xml for the appSettings section and parse it myself, using the workaround from this answer to AppSettings from custom files. This adds to my suspicion that this code is not commonly used in this mode, has been accepted as working and not reviewed, and could thus be buggy.
I'm sure it will receive scant attention with the new .NET Core configuration API replacing the old XML only one.
So you have two concerns as I understand:
OpenExeConfiguration does not fail for files with extensions other than "exe".
OpenExeConfiguration does not fail if configuration file not already exists.
I understand both points, but I'd say both of them are arguable.
Executable file does not necessary mean file with .exe extension. Yes, on Windows that's usually true, but let's take Linux for example (and we can do that because .NET is not restricted to Windows only). I can have executable .NET file with any extension (even notes.txt), or without extension at all, it doesn't matter. I can happily execute that file with "mono notes.txt" and it will run as usual.
Non existing configuration file is not an exceptional condition for Configuration object. It even has property named HasFile which indicates if that file exists or not. I can do the following with your code:
var config = ConfigurationManager.OpenExeConfiguration("c:\\notes.txt");
// config.HasFile == false here
config.AppSettings.Settings.Add("test", "test");
config.Save(ConfigurationSaveMode.Full, true);
// config.HasFile == true here, and file is written to disk
Not sure whether it could be called a bug or not but
As per this reference
According to
http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/3943ec30-8be5-4f12-9667-3b812f711fc9
the parameter is the location of an exe, and the method then looks for
the config corresponding to that exe (I guess the parameter name of
exePath makes sense now!).
It also gives a workaround --
ExeConfigurationFileMap map = new ExeConfigurationFileMap { ExeConfigFilename = "EXECONFIG_PATH" };
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
I have a Xamarin-Studio App for Android and I simply want to download files and save them locally. But when I try to create a file in the files folder I get an exception:
File.Create("data/data/com.company.app/files/newFile.png");
gives me:
System.UnauthorizedAccessException
Access to the path 'data/data/com.company.app/files/newFile.png' is denied.
What am I doing wrong?
You should use Environment or IsolatedStorage. For example:
var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var filename = Path.Combine(path, "newFile.png");
I am coding Xamarin with VS2013. I had the access denied error for a directory created with the application I am writing. My application creates a directory called /storage/emulated/0/POIApp by concatenating via:
System.IO.Path.Combine(Android.OS.Environment.ExternalStorageDirectory.Path, "POIApp");
I found that I had to use VS2013 to edit the "properties" of my application (POIApp), i.e., right-click the project icon in the solution explorer; choose properties from the pop-up menu. A new tab appears in the main VS2013 window. On the left there are a few choices, e.g., Application, Android Manifest, Android Options, Build, etc. Choose "Android Manifest". At the bottom of the main panel is a section "required permissions". My problem was solved when I checked "READ_EXTERNAL_STORAGE" and "WRITE_EXTERNAL_STORAGE".
Add the following permission to Android.Manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I finally realized that File.create() was not the problem. I had code like this:
string tmpFilePath = FilesDir.AbsolutePath.stringByAppendingPath (f.Path);
Java.IO.File tmpFile = new Java.IO.File( tmpFilePath);
tmpFile.Mkdirs ();
Yet, Mkdirs() does not only create all intermediate directories – as I had assumed – but also creates a directory at the file path itself. So the file could not be created because there already was a directory with the same name.
The correct way is:
string tmpFile = FilesDir.AbsolutePath.stringByAppendingPath (f.Path);
Java.IO.File tmpParentFolder = new Java.IO.File(tmpFile).getParentFile();
tmpParentFolder.Mkdirs ();
In my defense, an FileExistsAndIsDirectory exception would have been much more helpful than the UnauthorizedAccessException
Using Mono, I think must be the same as in Xamarin Studio.
var path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
File.Create(path + "newFile.png");
The connection string setting is below:
Name:
dbPersonConnectionString
Type:
Connection string
Scope:
Application
Value:
Data Source=|DataDirectory|\dbPerson.sdf
When I install & run the application, it looks for DB in C:\MyApp\Data\ folder. It should be C:\MyApp without additional \Data folder.
Should I simply create Data folder in my project and move DB files under that folder or I simply adjust |DataDirectory| -and how-?
EDIT:
string executable = System.Reflection.Assembly.GetExecutingAssembly().Location;
string path = (System.IO.Path.GetDirectoryName(executable));
AppDomain.CurrentDomain.SetData("DataDirectory",path);
This has been asked before. This MSDN post gives a good overview.
It should indeed default to your binaries folder, you can change it with AppDomain.SetData() . If you change it, better do it early.
AppDomain.CurrentDomain.SetData("DataDirectory", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
This should work always because Directory.GetCurrentDirectory() may return other directory than the executable one
This one solved my problem
AppDomain.CurrentDomain.SetData("DataDirectory", Directory.GetCurrentDirectory());
i've written a console application deploy.exe which runs a batch script.
Process p1 = new Process();
p1.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "installer.bat";
p1.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p1.Start();
p1.WaitForExit();
p1.Close();
the installer.bat conatins the following command.
\shared1\lists\list1.cmd
If i run the executable byitself it runs successfully.
However i needed it to run in a windows installer project. So i made a setup and deployment project and added the deploy.exe successfully as custom action upon install.
It runs fine but when it starts to execute the command i get this error
"The filename, directory name, or volume label syntax is incorrect".
any help?
Try printing out what the value of AppDomain.CurrentDomain.BaseDirectory is. It may not be where installer.bat is when you are installing it.
Also, you tried adding the bat file to a custom action (if that is even possible)?
And, would it possible to move what is in the bat to the exe?
Is it a problem in your batch file?
Check this:
\\shared1\\lists\\list1.cmd
should probably be
\\shared1\lists\list1.cmd
Note the extra \ chars in your original command. That would cause the batch file to give that error.
the error seems to be inside the script which was being executed. It contained environment variables %kind%, which were not acceptable by the installer for some reason. So it was working properly outside the installer and not properly when the installer was calling it.