exePath is invalid exception in ConfigurationManager.OpenExeConfiguration - c#

I have a windows service which is installed to C:\Windows\System32. It has a usual .config file, where some app settings are stored. I have another app that writes some values to this config. When i run this app it throws an exception at this line
var config = ConfigurationManager.OpenExeConfiguration(serviceExePath);
The exception says: An error occurred loading a configuration file: The parameter 'exePath' is invalid. Parameter name: exePath
When I put my windows service to another folder everything is ok! Is it due to some access violation rules or smth like that? Is there any way to use System32 folder for my service and open its config?
OS: Windows 7 x64

It is a poor choice for a file location. That directory belongs to Windows, it isn't suitable for your own apps. For one, you'll need admin privileges to open files in that directory. You don't get that without a manifest to trigger the UAC prompt.
For another, that directory is virtualized on the x64 version of Windows. A 32-bit app trying to access files there will be redirected to c:\windows\syswow64.
I could have been more accurate if you posted the stack trace. But, just don't do it.

Note that despite the name of the parameter being 'exePath', you should be passing in the name of the .config file, so you might need to append '.config' based on what's in your serviceExePath folder.
http://msdn.microsoft.com/en-us/library/ms224437.aspx
exePath
Type: System.String
The path of the configuration file. The configuration file resides in the same directory as the executable file.
As it stands, I get the feeling it's trying to load the actual .exe as a config file, which certainly explains why it considers it to be invalid :)

Give this a try, it has helped me in the past:
http://sandblogaspnet.blogspot.com/2009/06/reading-from-configuration-file-in-net.html

Related

FileNotFoundException is occur while running Wpf application on 32bit machine

I created setup file using Inno setup.I have exe,dll and one xml file in my setup.
When I install on 64 bit machine it works fine means it take xml file from directory where exe is present.
But When I install same setup on 32 bit machine it take dll path but while accessing xml file it takes path of desktop where shortcut of exe is present and showing FileNotFoundException.
Thanks
Your application is most likely not specifying pathnames on the files it is trying to open, so it is expecting to find them in the current directory. Inno Setup by default does not set the "Start In" field on shortcuts its creates; this causes Windows to pick a directory itself, which usually won't be the directory containing your application.
In virtually all cases, this is something that should be corrected at the application level. Properly designed GUI applications should not expect to be started from a particular directory; they should always specify full pathnames on files they open. In Delphi or C++Builder, for example, it's possible to get the full pathname of the directory containing the application EXE by calling: ExtractFilePath(ParamStr(0)). To get the full path of a file named "File.txt" in the application directory, use: ExtractFilePath(ParamStr(0)) + 'File.txt'.
To get path of working directory of application while loading xml file in code.
string WorkingDir=System.AppDomain.CurrentDomain.BaseDirectory
XDocument temp_xdocument= XDocument.Load(WorkingDir+"file.xml");
It works for me.

Create a Setup File Windows.Net C#

I have created a windows application setup program, it needs to have a text file in the application folder. The file is also included while creating the setup.
Once the setup successfully completes and my program tries to modify the file based on user input, its simple throwing an exception.
I am using Windows 7 Home Premium OS.
Any suggestion/help will be great to overcome this issue.
This is normal on a Vista or Win7 machine. Or a properly secured XP machine for that matter. The normal install location for programs, like c:\program files\your company\your app, is read only for most users. UAC is a counter-measure to malware messing with programs.
You'll need to store the text file into a writable location, the AppData folder. In the Setup project, right-click "File system on target machine" and select User's Application Data Folder. Find that file back at runtime through Environment.GetFolderPath, passing Environment.SpecialFolder.ApplicationData. Or use "User's Personal Data Folder" if the user should be able to find it back easily through the Documents folder.
What exception is being thrown? It could be a UAC issue.

C# service location

I have a service in C#, it uses a config.xml file for configuration.
I want to deplay the xml along side with the service executable. But I can't seem to understand where to find the service exe installed location at runtime so that I could find/load the config.
Help please.
The static method Assembly.GetEntryAssembly() will give you a reference to the entry assembly (the .exe file), and the Location property will give you the location of the file:
Assembly.GetEntryAssembly().Location
Another way around, if you know of a type in the entry assembly, is to use the Type.Assembly to get a reference to the assembly:
typeof(Program).Assembly.Location
If you need just the directory path, use the static Path.GetDirectoryName() method.
Off topic: have you considered the configuration API built into .NET? I am not saying this will be better in your specific case, but I guess it is worth considering before rolling your own configuration framework.
Do you mean that you are building a project in visual studio and you want to know where your compiled EXE is saved to? You will find this in "[project folder]\bin\debug".
Or do you mean you already have a service installed on your computer and you want to know where its running from? To do this you can right click on the service and choose properties. This will show the path of the file.
Your executable is located in AppDomain.CurrentDomain.BaseDirectory.
Some of my service projects load a custom log4net configuration like this.
var file = new FileInfo( AppDomain.CurrentDomain.BaseDirectory + "/" + filename );
if (file.Exists) {
XmlConfigurator.ConfigureAndWatch( file );
}
The same service uses an normal app.config file for standard configuration.

Self-Updating .NET client application which needs to write in the Program File folder

Similar to: Request Windows Vista UAC elevation if path is protected?
I have a .NET Client Application installed in c:\Program Files (Windows Vista). This application should update itself, but it doesn't because of permission issues. The auto-updater should simply replace a couple of assemblies, but they are all located under c:\Program File and the application throws the following exception:
System.UnauthorizedAccessException:
Access to the path 'C:\Program
Files...' is denied.
I have no control on where the application could be installed and the permission. Is there any workaround for this? Is it possible to request the Administrator rights for a couple of seconds? Is it possible to pop a UAC window? I am pretty sure that there a workaround... Otherwise, how Firefox would be able to update itself?
Thanks in advance for the help and ideas!
Could you use a Click Once deployment method? We use this for an internal application and users have no problems with permissions when we publish a new version. They are prompted to install the update when they launch the app (if a new version exists) and it installs without a hitch.
You can't elevate a process's permissions halfway through, but you can start up another separate process with higher permissions that can do the work for you.
Get your main application to put all the files / installation details into a low-permission temporary location. When you're ready, start up a smaller application whose only job is to copy over those files to the Program Files directory (and maybe restart your main application with the new updates). Mark that application as requiring the needed permission to copy to the Program Files directory or write to the registry (or whatever else is needed).

How does default/relative path resolution work in .NET?

So... I used to think that when you accessed a file but specified the name without a path (CAISLog.csv in my case) that .NET would expect the file to reside at the same path as the running .exe.
This works when I'm stepping through a solution (C# .NET2.* VS2K5) but when I run the app in normal mode (Started by a Websphere MQ Trigger monitor & running in the background as a network service) instead of accessing the file at the path where the .exe is it's being looked for at C:\WINDOWS\system32. If it matters The parent task's .exe is in almost the same folder structure/path as my app
I get a matching error: "System.UnauthorizedAccessException: Access to the path 'C:\WINDOWS\system32\CAISLog.csv' is denied."
My workaround is to just fully qualify the location of my file. What I want to understand, however is "What is the .NET rule that governs how a path is resolved when only the file name is specified during IO?" I feel I'm missing some basic concept and it's bugging me bad.
edit - I'm not sure it's a.NET rule per se but Schmuli seems to be explaining the concept a little clearer. I will definitely try Rob Prouse's suggestions in the future so +1 on that too.
If anyone has some re-wording suggestions that emphasize I don't really care about finding the path to my .exe - rather just didn't understand what was going on with relative path resolution (and I may still have my terminlogy screwed up)...
When an application (WinForms) starts up, the Environment.CurrentDirectory contains the path to the application folder (i.e. the folder that contains the .exe assembly). Using any of the File Dialogs, ex. OpenFileDialog, SaveFileDialog, etc. will cause the current directory to change (if a different folder was selected).
When running a Windows Service, its containing folder is C:\Windows\System32, as that is the System folder and it is the System (i.e. the Operation System) that is actually running your Windows Service.
Note that specifying a relative path in most of the System.IO objects, will fall back to using the Environment.CurrentDirectory property.
As mentioned, there are several ways to obtain the path of the service executable, using Assembly.GetEntryAssembly() or Assembly.GetExecutingAssembly() and then using either the Location property or the CodeBase property (be aware that this is the file path, not directory, of the executable).
Another option is to use:
`System.IO.Directory.SetCurrentDirectory( System.AppDomain.CurrentDomain.BaseDirectory );`
Make the call in the Service's OnStart method, applying it to the whole application.
It is based on the current working directory which may or may not be the same as where your application resides, especially if started from a different program or a shortcut with a different working directory.
Rather than hard code the path, get the path to your program and use it. You can do this with something like this
Assembly ass = Assembly.GetEntryAssembly();
string dir = Path.GetDirectoryName(ass.Location);
string filename = Path.Combine( dir, "CAISLog.csv" );
This assumes that the entry assembly is where your file is. If not, you can change up getting the assembly for something like;
Assembly ass = Assembly.GetAssembly( typeof( AClassInYourAssembly ) );
Relative Path resolution never works against the path of the launching executable. It always works against the process' Current Directory, and you can't really expect that to always be set to the directory the .exe lives in.
If you need that behavior, then take care to find out the right path on your own and provide a fully qualified path to the file operations.
You can use this to specify a path that resides at the same path of your exe #"..\CAISLog.csv". Please note that the double dots refer to the parent directory of where ever your .exe lies.
RWendi

Categories