Environment.GetEnvironmentVariable("ProgramFiles") doesn't return expected result
-
09 Ağustos 2012 Perşembe 21:23
Hi,
I have a C# program that's calling
Environment.GetEnvironmentVariable("ProgramFiles")
on my x64 development machine. It's getting back "C:\Program Files (x86)", which is kind of surprising. If I run the command in my Visual Studio Command Prompt (2010) I see:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>echo %ProgramFiles(x86)% C:\Program Files (x86) C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>echo %programfiles% C:\Program Files
The C# program is set to compile in Any CPU mode. I might expect this behavior if it were set to compile in x86 mode.
-Eric
Tüm Yanıtlar
-
09 Ağustos 2012 Perşembe 21:31
-
09 Ağustos 2012 Perşembe 21:36
Is this console app ?
Windows forms ?
Regards,
Ahmed Ibrahim
SQL Server Setup Team
My Blog
This posting is provided "AS IS" with no warranties, and confers no rights. Please remember to click "Mark as Answer" and "Vote as Helpful" on posts that help you.
This can be beneficial to other community members reading the thread. -
09 Ağustos 2012 Perşembe 22:01Moderatör
What happens if you use Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)?
The advantage of this approach, btw, is that you can get Environment.SpecialFolder.ProgramFiles or Environment.SpecialFolder.ProgramFilesX86 - as needed. Both are options.
This is the preferred method of getting the proper folder, not using the environment variables.
Reed Copsey, Jr. - http://reedcopsey.com
If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful". -
10 Ağustos 2012 Cuma 00:52
I get the same thing:
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) "C:\\Program Files (x86)" string
-
10 Ağustos 2012 Cuma 00:55
It's an nUnit test that compiles as a DLL.
The complete code snippet looks like:
if (myInstallTypeIs32bit) { //For x86 on an x64 box, look in ProgramFiles(x86) filePath = filePath.Replace(@"C:\Program Files", Environment.GetEnvironmentVariable("ProgramFiles(x86)")); } else { //Replace their program files directory with the one specified in the environment variable, in case it's different filePath = filePath.Replace(@"C:\Program Files", Environment.GetEnvironmentVariable("ProgramFiles")); }
Basically it's testing that a deployment completed successfully.
-
10 Ağustos 2012 Cuma 01:37
I did some tweaking there, was some weird stuff in my configuration manager, but I'm certain that everything is compiling in any cpu mode:
------------- 00:00.224 - Success - Debug Any CPU - UnitTests.csproj 00:00.148 - Success - Debug Any CPU - AnotherProject.csproj Total build time: 00:00.388 ========== Rebuild All: 2 succeeded or up-to-date, 0 failed, 0 skipped ==========
I wrote a simple console app. It shows the wrong path when compiled as x86, but not when compiled as Any CPU:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestEnvironmentVariable { class Program { static void Main(string[] args) { Console.WriteLine(Environment.GetEnvironmentVariable("ProgramFiles")); Console.WriteLine(Environment.GetEnvironmentVariable("ProgramFiles(x86)")); Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)); Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)); Console.WriteLine("Press any key to continue..."); Console.ReadLine(); Console.WriteLine("Any key but that one..."); Console.ReadLine(); } } }
Here's the output:
Compiled as any cpu: C:\Program Files C:\Program Files (x86) C:\Program Files C:\Program Files (x86) Press any key to continue... Compiled as x86: C:\Program Files (x86) C:\Program Files (x86) C:\Program Files (x86) C:\Program Files (x86) Press any key to continue...
-
10 Ağustos 2012 Cuma 01:50
- Yanıt Olarak İşaretleyen Charles Foxtrot 10 Ağustos 2012 Cuma 14:07
-
10 Ağustos 2012 Cuma 02:13
The ProgramFiles environement variable is virtualized in function of the x86 / x64 platform.
In the properties of your exe visual studio project, on the build tab, you can choose the target platform:
x86: the program will start in 32 bits mode
AnyCPU : the program will start in 32 bits mode on 32 bits OS and 32 or 64 bits mode on 64 bits OS. By default on 64 bits OS we use 64 bits mode. If you have VisualStudio 2012, a new "Prefer 32-bit" checkbox allow AnyCpu programs to starts in 32bits mode (equivalent to x86 on user computers, but allow the program to works on 64 bits servers that do not have a 32 bits compatibility box installed).
x64 : the program will start in 64 bits mode
ARM : reserved for Metro styled apps that will run only on ARM processor based tablets.
So in x86/AnyCPU +prefer 32-bit modes, ProgramFiles environment variable is defined by Windows to c:\Program Files (x86) (as Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles))
In x64/AnyCPU (without prefer 32-bit) modes, ProgramFiles environment variable is defined by Windows to c:\Program Files. on 64 bits computers (AnyCPU programs on 32 bits OS, ProgramFiles environment variable is defined by Windows to c:\Program Files (x86) (as Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles))
Many environement variables and special folder are defined by Windows at program start. See : http://technet.microsoft.com/en-us/library/dd560744(WS.10).aspx and search for "Same as CSIDL_" for all Environement variables defined by Windows at program startup (not all of them are virtualized in function of the platform).
The general idea behind 32/64 bits platform virtualization in Windows is that 32bits application are virtualized and 64 bits applications aren"t. With a major implication : 32 bits applications doesn't see 64bits non virtualized data that are hidden by virtualization. So if you want to see both the platforms, the best solution is to run in 64 bits modes.
My solution to this : for exe that should supports both modes, generate "MyProgram" twice: "MyProgram.exe" with x86 target platform and "MyProgramX64.exe" with a x64 target. The x86 program is always started (for example by double-clicking program icons) and at lauch time it identify the OS with Environment.Is64BitOperatingSystem and in this case launch its x64 counterpart and exit immediately (Note that this reduce the need to refactor installation programs, but it isn't very performant. If you need launch performance, do the additional work in the installer or more generally before launching the program).
- Düzenleyen RBancel 10 Ağustos 2012 Cuma 16:49
-
10 Ağustos 2012 Cuma 14:07That fixed it. Thanks.