This question was originally posted as "Error occurred loading a configuration file: Access to path c:\Program Files (x86)\… denied", but I didn't have much success finding a solution.
My application was written on Windows 7, it's a 32-bit application written with Visual Studio 2010. When I try to deploy this application on a Windows 8 system, the app fails during form_Load, with an error about access to a tmp file in the EXE's directory. I am not creating this temp file directly, but it has a name which is consistent with one generated by the C# GetTempFileName method. The name of the EXE config file (MyApp.exe.config) is also referenced in the error message.
I use the ConfigurationManager to store all of my application settings at startup, so I'm guessing that it is somehow related to this. If I build the application on a Windows 8 system it runs fine on the Windows 8 system, but generates the same error if deployed on a Windows 7 system. I don't know yet exactly what line of code is causing the error but the calls boil down to
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings.Add(settingName, settingValue);
config.Save();
ConfigurationManager.RefreshSection("appSettings");
Both the Windows 7 and 8 systems are 64-bit but the application is 32-bit. Thanks in advance for any advice in solving this.
I use the Settings class to handle the configuration data and the TEMP variable is what I expect it to be, my user\AppSettings\Local\Temp.
The problems encountered were on an evaluation version of Windows 8, this was all that was available. Running the application on a licensed version of Windows 8 Pro it works perfectly.
Thanks for the replies.
Related
I faced very strange behaviour - after I overwrite .NET exectables with new versions from network drive it cannot start.
When try to start from Windows Explorer it shows me following error:
[Window Title]
C:\Programs\zzz\clients.net\zzzNet.exe
[Content]
C:\Programs\zzz\clients.net\zzzNet.exe
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
I tried to execute following commands:
SxsTrace Trace -logfile:SxsTrace.etl
SxStrace Parse -logfile:SxSTrace.etl -outfile:SxSTrace.txt
And got following result:
=================
Begin Activation Context Generation.
Input Parameter:
Flags = 0
ProcessorArchitecture = AMD64
CultureFallBacks = en-US;en;ru-RU;ru
ManifestPath = C:\Programs\zzz\clients.net\zzzNet.exe
AssemblyDirectory = C:\Programs\zzz\clients.net\
Application Config File = C:\Programs\zzz\clients.net\zzzNet.exe.Config
-----------------
INFO: Parsing Application Config File C:\Programs\zzz\clients.net\zzzNet.exe.Config.
INFO: Parsing Manifest File C:\Programs\zzz\clients.net\zzzNet.exe.
INFO: Manifest Definition Identity is (null).
ERROR: Line 0: XML Syntax error.
ERROR: Activation Context generation failed.
End Activation Context Generation.
It is quite simple .NET application (1 exe + 8 dll files). It was built for .NET 3.5 Client Profile.
I not defined any special "manifest" there. Just clicked "New Windows Forms Project" in Visual Studio and developed it.
Also app.config does not contain anything special - only primitive standard settings - appSettings and userSettings sections.
On PC where I developed it all is perfectly works. Problems only began when I copy these binaries to this particular VM and try to start.
Also please note - these executables were not installed in GAC or such, I just copied them into a folder on VM and started. And when it was 1st time all was working fine.
So, the problem pattern is following:
Copy .NET execuatbles to new VM (it is Win 7 x64), run it, all is working fine. Close it.
Build new version of .NET execuatbles on host PC, copy new .NET execuatbles to VM (with files overwriting).
Try to start - got mentioned problem.
After some shaman-style actions (like OS reboot, etc) it begin to work but why that happened at all?!
Why replacing .NET executables with new versions is causing SUCH HUGE PROBLEMS?!
Also the BIG QUESTION - is there any special procedure to replace .NET executables to keep them working? Because it is a new app development, I do not want lost so much time on every new executables installation. :-\
Could you please help? Because it looks completely weird!
Thank you in adance.
PS. I checked all VS projects - all they have PlatformTarget=AnyCPU. Also in run-time I can see ProcessType=MSIL (I show this info in AboutBox for application). So, there is no mix of x86/x64 binaries.
It seems that was related to mapped network drive behavior.
When I copied new files from network drive folder it copied wrong files - a strange random mess of new files and older ones (which were there before I updated them on VM host).
The scenario to make it working:
on VM: delete all files in a folder on network drive
on VM host: copy new files into a folder which is mapped as network drive on VM
on VM: copy files into target folder
on VM: run application - it works now
Weird thing. I remember I have seen something similar with Windows Explorer on Windows 2008 behaviour when copying updated win32 binaries.
I am moving three Windows Services (.NET 3.5) from Windows Server 2003R2, to Windows Server 2012 R2 (.NET 4.5).
The first two went well. Reading registry settings from
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MyCompany\MyApplication].
Now here´s the funny stuff - the third one only works when I store settings in
[HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MyApplication] (whitout Wow6432Node)?
And, if I try to run the service with settings in 32-bit registry it reads the settings ok but I get this assembly binding error instead:
System.BadImageFormatException: Could not load file or assembly 'Oracle.DataAccess, Version=4.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342' or one of its dependencies. An attempt was made to load a program with an incorrect format. The other two, using the same dll, works fine.
Any ideas? What is different in the third Windows Service?
Since all applications using the same code to read the registry I don´t think that´s the problem. Her´s the code (simplyfied) anyway.
private string getRegistrySetting(string keyName)
{
string softwareSubkeyName = "SOFTWARE";
using (RegistryKey softwareSubkey = Registry.LocalMachine.OpenSubKey(softwareSubkeyName, false))
{
string lmSubkeyName = "MyCompany\\MyApplication;
using (RegistryKey lmSubkey = softwareSubkey.OpenSubKey(lmSubkeyName))
{
return lmSubkey.GetValue(keyName).ToString();
}
}
}
First, you need to make sure that all your executables have the target platform set to x86 (and not to AnyCPU) on the build tab of the project's property pages (caveat: this is a per-build-configuration setting, you need to set the target platform for both Debug and Release build).
Then you need to make sure that you also deploy the 32-bit version of any third-party components such as Oracle.DataAccess. The reason is that a 32-bit process cannot load a 64-bit dll and vice versa.
The target platform is relevant because it determines if your process will be started as a 32-bit or 64-bit process. If your executable runs as a 64-bit process Registry and file system redirection won't be in place - as a result your process will read and write directly to HKEY_LOCAL_MACHINE\SOFTWARE\ and not to the Wow6432Node subnode.
I am facing very strange issue:
I got a 64 bit c#.net application on 64 bit Windows Server 2008 R2 machine and it is being invoked by a Windows Service and it is started under Local System User, Moreover,this 64 bit c#.net application launches 32 bit java application and this java application has application data folder to C:\Windows\SysWOW64\config\systemprofile\AppData. 64 bit c#.net application has app data folder to C:\Windows\System32\config\systemprofile\AppData
So for 32 bit application app data folder is (in case of Local system User):-C:\Windows\SysWOW64\config\systemprofile\AppData
and for 64 bit application app data folder is(in case of Local system User):-C:\Windows\System32\config\systemprofile\AppData
Please Note: this is not typing mistake that they refer to opposite folders(it is a decision by microsoft for 64 bit OS), you can read https://msdn.microsoft.com/en-us/library/aa384187.aspx for detailed explanation.
Now, I need to write few files to 32 bit app data folder from 64 bit application as these files would be used by 32 bit java application.
So, I need to know How I can get 32 bit app data folder from 64 bit application using c#.net.
Important Note: this issue would be faced when application is launched under local system user (i.e. application has been launch by window services) and there won't be any issue when a user explicitly launches the application beacause in this case,user app data folder would be same for 64 bit and 32 bit application.
You first check if you actually are running inside of a 64 bit process on a 64 bit OS. And if so, you construct the path yourself. Otherwise you can just retrieve the system path and append your target path.
String path;
//detect if the current application is 64 bit and running on a 64 bit system
//NOTE: needs .NET Framework 4 to work
if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess)
{
path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64");
}
else
{
path = Environment.GetFolderPath(Environment.SpecialFolder.System);
}
//append your target path
path = Path.Combine(path, #"config\systemprofile\AppData");
Please note that using EnvironmentIs64BitOperatingSystem and Environment.Is64BitProcess requires at least .NET-Framework 4.
The simplest solution is to rebuild the C# application as 32-bit, or to use 64-bit Java.
If you can't do either, create a 32-bit application that does nothing but look up the application data path, and run it from your C# application. The 32-bit application could be written in C, C#, or Java.
Are you using "shortcut" keyword to point appdata directory, eg %APPDATA%? Could you use a direct path, eg #"C:\Users\%username%\AppData\Local"
This is the same answer as #2 above (via Sebastian Baumhekel), with some errors corrected. I am on Win 7 and have the same issue. As some have pointed out this may not be future OS safe... However it solves my current issue.
The issue is on 64bit Win7 when you run a 32bit Windows Service as Local System user and ask for this folder:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
It returns the 64bit version (with System32):
C:\Windows\System32\config\systemprofile\AppData\
Main point of clarification (as OP states):
SysWOW64 gets 32bit application data...
System32 gets 64bit application data...
This from OP link:
https://learn.microsoft.com/en-us/windows/desktop/WinProg64/file-system-redirector
I just wasted 4 hours of my life getting to the bottom of this so I wanted to clarify!
public 32bitWindowsServiceOn64bitWindows()
{
// Note: this service is configured to run as "Local System" user...
string appdata;
// need to do this, because this runs as Local System user...
// which gets the wrong SpecialFolder.ApplicationData (ie, System32 for 64bit apps) should be SysWOW64 (for 32bit apps)
if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess)
{
// the application is a 64 bit app
appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32");
}
else
{
// the application is a 32 bit app
appdata = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64");
}
// Append your target path. Do you want Local or Roaming?
appdata = Path.Combine(appdata, #"config\systemprofile\AppData\Roaming\MyApp");
//appdata = Path.Combine(appdata, #"config\systemprofile\AppData\Local\MyApp");
...
I have following lines of code:
System.Reflection.AssemblyName assemblyName =
System.Reflection.AssemblyName.GetAssemblyName(#"C:\inetpub\wwwroot\wss\VirtualDirectories\22687\bin\log4net.dll");
After executing it, I get a System.IO.FileLoadException - Could not load file or assembly or one of its dependencies. Access is denied..
If i copy the file and try the same in a different directory (for example: #"C:\inetpub\wwwroot\wss\VirtualDirectories\22687\log4net.dll") I don't get the Exception, even if I set the permission for the file exactly the same.
Can anyone point me to the right direction?
I'm running Windows Server 2008R2, SharePoint 2010, IIS7 and Visual Studio 2010.
edit: It works on LINQPad. I run the Application from the IIS App Pool under the same user as the LINQPad Process.
I'm writing a program with C# on Visual Studio 2012. I have encountered the following problem.
The first, I configure the assembly name on project C# is "ABC", I built and it generated the executive file is "ABC.exe", then when run this exe on the PC (Windows 8), the Task Manager displays process name is "ABC" => It's ok!
And then, I changed assembly name to "CDE", rebuild and it generate file "CDE.exe".
And when run "CDE.exe" file on above Window 8 PC, the Task Manager displays process name still is "ABC"?
Note that this problem occurs only on the PC run Windows 8. I tested on 2 PC run Windows 7, the process name will update is "CDE.exe".
Someone can tell me what happen?
Windows is picking up the value of the AssemblyTitleAttribute specified for your executable assembly.
Open up AssemblyInfo.cs, and you should find this line:
[assembly: AssemblyTitle("ABC")]
Change that (and any other attributes in the same file) accordingly.