How should my program decide to install under "Program Files (x86)"? - windows

Just out of curiosity, if I am creating a program installer, how should I decide in which "Program Files" directory to install to? On 32-bit systems, the environmental variable "%programfiles%" is good enough. However, on 64-bit systems, 32-bit programs should not install to that folder and instead to "%programfiles(x86)%", which as I understand points to "C:\Program Files (x86)". My question is: How should the installer decide which environment variable to use? Will the value of "%programfiles%" change for a 32-bit application, or should I always check first whether "%programfiles(x86)%" exists before using "%programfiles%", or should I do something entirely different?
Thanks! This is just out of my own curiosity, as I try to get used to 64-bit operating systems.

When the 32-bit program (installer in your case) asks the system to resolve the ProgramFilePath constant (check the exact name in MSDN), the system does not return C:\Program files, but C:\Program files(x86). So it's the system that decides, not the application.

I'm pretty certain that I read somewhere that Windows did this for you automagically. In other words, if your installer was 32-bits, it would be routed to the x86 directory variant even though you were trying to install into Program Files.
I'm sure I read this on The Old New Thing but here's a link that supports the contention until I can find that one.
Ah, yes, here it is, from the ever useful Raymond Chen.
Commenter Koro is writing an installer in the form of a 32-bit program that detects that it's running on a 64-bit system and wants to copy files (and presumably set registry entries and do other installery things) into the 64-bit directories, but the emulation layer redirects the operations into the 32-bit locations. The question is "What is the way of finding the x64 Program Files directory from a 32-bit application?"
The answer is "It is better to work with the system than against it." If you're a 32-bit program, then you're going to be fighting against the emulator each time you try to interact with the outside world. Instead, just recompile your installer as a 64-bit program. Have the 32-bit installer detect that it's running on a 64-bit system and launch the 64-bit installer instead. The 64-bit installer will not run in the 32-bit emulation layer, so when it tries to copy a file or update a registry key, it will see the real 64-bit file system and the real 64-bit registry.

Related

Is my 32 bit & 64 bit installers in the wrong directories?

I'm having trouble installing a 64 bit program on my windows PC.
I'm running windows 7 64 bit.
Looking in regedit after a bit of googling I noticed the files seem to be in the opposite directories to what I think they should be.
Nope, those look correct to me. They are indeed confusing at first, and can be difficult to talk about.
System32 is the native system directory, and happens to be misleadingly named on a 64-bit system.
SysWow64 indicates the system directory for the Windows (32)-on-Windows 64.
Note of course that only a 64-bit application, or one that has disabled redirection, can use a path containing "System32" to reach the 64-bit files it contains.

Is it bad idea to put 64b application into ProgramFiles(x86)?

We are shipping application, that is 32b, and, therefore, put into ProgramFiles(x86) directory. There is x64 'plugin' for it, running as a separate process (service), and now we're deploying it into the main application's subdirectory. The plugin isn't deployed on x86 systems.
Now, the question - isn't this (having x64 exectuable in x86 ProgramFiles) considered as bad idea? Can this solution have negative impact on (something)?
Thanks!
It has no negative impact, and in fact, Visual Studio also does this (it installs its 64-bit native compilers into the (x86) directories).
This is only problematic if it's a "real" 64-bit application that expects to be where it's supposed to be (wrt "Program Files"), as certain WinAPI functions that give you this directory work differently for 64-bit and 32-bit applications.
For an x64 program, the %PROGRAMFILES% environmental variables and their analogues are pointing to the Program Files (no x86) directory. So there may be some problems with locating the files that were put in the wrong directory.
Since your app is 32bit, there shouldn't be any problems.

launching correct installer for 32 and 64-bit apps

We have an application which, for various reasons, needs to be compiled as both a 32-bit and 64-bit app. The thing is, we want to distribute both setup files (msi) on a single CD. Is there a launch condition or autorun.inf entry that we can use to know which setup.exe to launch? Or do we need to write a separate little exe that gets called by autorun, and which determines the OS, and calls the appropriate setup.exe?
There does not appear to be any 32/64bit detection support inherent in autorun.inf files.
The convention that most applications which supply a 32 and 64 bit MSI follow is similar to the second option you mention.
Create a single 32bit setup.exe application (so that it will run on either platform). Ideally this will be written in C/C++ so that it is as small and quick as possible, and has no dependencies on other libraries/frameworks (eg. static linked).
Detect if you are running on 64bit or not (see sample code for Windows API IsWow64Process function
Execute the appropriate MSI
You can use a custom action to detect the OS, then call the right installer.
I've given an example here: Single MSI to install correct 32 or 64 bit c# application

SHGetSpecialFolderPath, how to access 64bit CSIDL from 32bit application

Is there a way from a 32bit application running on a 64bit system to have access to the default folders for 64bit applications?
For example, using SHGetSpecialFolderPath with CSIDL_PROGRAM_FILES from a 32bit application returns "C:\Program Files (x86)' If the same call was used from a 64bit application, I would get "C:\Program Files". Is there a way of getting that "C:\Program Files" from a 32bit application?
A related question here does not help SHGetFolderPath() 32 bit vs 64 bit nor does supressing the wow64 filesystem redirection before calling SHGetSpecialFolderPath
Answering my own question, it seems it is not possible with SHGetSpecialFolderPath. In Vista and later, using the replacement function SHGetKnownFolderPath allows it with FOLDERID_ProgramFilesX64
I believe the whole reason for having separate folders was to prevent 32 and 64 bit applications from mixing. Therefore, you shouldn't need to see a folder belonging to a different bitness from your application.
You may have a very good reason, but I don't see one in your question as posted.

32-bit cluster.exe on 64 bit Windows 2008

We have an installation program that runs in Perl 32-bit. This program needs to get information on cluster resources, so it runs cluster.exe (using backticks) and parse its output.
On Windows Server 2003 this went well, as a 32-bit version of cluster.exe existed under syswow64. However, such a 32-bit version does not exist on Windows Server 2008, so the backticks run of cluster.exe says it can't find such an executable, as 32-bit process look for it under syswow64.
Can someone think of a way we can bypass this problem and get the cluster resource information?
One manual way is to copy the 64-bit version of cmd.exe from system32, and then run it with "/c cluster.exe" which will start the 64-bit cluster.exe under system32. (Copying the cluster.exe won't work well, as it can't find the cluster cache.) However, this is only good as a manual workaround, and not as a solution to all users.
Is there another way to cause windows to start the 64-bit cluster.exe?
Thanks,splintor
PS
A similar question was asked on technet a month ago, but didn't get a real answer.
I found two possible solutions:
One is to write a small 64-bit application named cluster.exe that simply calls %SystemRoot%\System32\cluster.exe (using system()), and put it under %SystemRoot%\syswow64. Since it is a 64-bit application, the correct 64-bit cluster.exe application will be called.
Another solution is to use the sysnative redirection (as explained here), so now we check - if %SystemRoot%\System32\cluster.exe exists, we use it, else if %SystemRoot%\Sysnative\cluster.exe exists we use it, else we use plain cluster.exe.
Note: this is very similar to this telnet.exe problem that just got answered.

Resources