Installation path for .Net based components building using Any CPU - msbuild

.Net Assemblies built with AnyCPU will JIT to 64-bit code when loaded into a 64-bit or 32-bit process based on the CPU. I am creating a WiX installer.
What should be the default path (Program File x86/Program File) for the components built with AnyCPU option? Shall the installer check the platform and set the appropriate path or are there any other ways to handle it?

At this point in time, I'd recommend installing to ProgramFilesFolder (Program files (x86)) as that is present on both 32-bit and 64-bit computers. 32-bit is the closest thing (at this time) Windows has for "Any CPU".
Note: This does change as WOW is removed from 64-bit Windows. You can already remove the WOW subsystem from Windows Server, in which case you need to provide a package that targets the appropriate architecture. It isn't clear if/when WOW will be removed from Windows client.

Related

Remove Files if the installer folder is Program Files

I have Wix Installer for my 32-bit Application i.e. it always set up the files in Program Files(x86). SO when the user installs it on the 32-bit machine I want to remove some of the dlls from it.
I am not registering any values in Registry and don't want to that way. Is there any other way than this?
Yes, you do need separate MSI files for 32-bit and 64-bit, assuming that you have 64-code that you want to install and run. 32-bit apps will install on 64-bit systems and run in 32-bit mode, but it appears that you have 64-bit Dlls.
This is a good outline of why you need two installs:
https://blogs.msdn.microsoft.com/heaths/2008/01/15/different-packages-are-required-for-different-processor-architectures/
For example there are different folder locations such as ProgramFilesFolder for 32-bit program files and ProgramFiles64Folder for 64-bit setups.
and this link:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa367451(v=vs.85).aspx
points out that 32-bit packages can contain only 32-bit components, and 64-bit packages can contain 64-bit and some 32 bit components.

Disable registry redirection in WiX

I'm using WiX to deploy my application. This application uses a registry key which is shared between x64 and x86 processes. Thus it must not use the Wow64Node. The application uses the KEY_WOW64_64KEY flag to achieve this.
But how can this be done using an MSI build with WiX? Currently I use an x86 and an x64 version of the installer, but that gives me a large overhead. Is it possible to disable registry redirection in WiX? I found the DisableRegistryReflection attribute, but that does not seem to have influence on redirection. Another idea would be to merge the two installers into a single file, like it is possible with languages. But I have in mind that that's not supported.
This could be done with an unified 32/64-bit package, but WiX doesn't support it. Some commercial setup authoring tools support it.
When using separate packages, 32-bit installers will use the 32-bit location on 64-bit systems. So to avoid registry redirection you should distribute a 32-bit package for 32-bit systems and a 64-bit package for 64-bit systems.
In 64-bit installers the registry entry component needs to be marked as 64-bit. In WiX you can do this by setting Win64 to "yes" for your registry components.

COM registration with WIX in 32bit and 64bit Windows

I created an installer for my AnyCPU DLLs. I've marked my assemblies with teh Assembly=.net directive in my project as well. The installer seems to be able to register the COM servers successfully on my XP 32bit machine, but fails to do so in my Windows7 Machine. I did run the installer in admin mode. Also I looked up the Win764 registry and found those CLSIDs in the reigstry. So looks like the MSI did put some entries in the registry but somehow they are not being recognized as valid COM Server entries (OLE Viewer also didnt enumerate my server).
Any idea why this would happen? Any extra config do I need to add to my project?
thanks
Apparently you need to compile your msi as a 64-bit native binary to have the dlls registered in 64 bit mode.

Is there any way for an MSBuild project to determine whether the 32-bit or 64-bit version of MSBuild is running?

After having found the answer to my question about the 64-bit version of MSBuild attempting to load 32-bit extensions, it has now become necessary for me to determine whether the 64-bit or 32-bit version of MSBuild is running so I can load the correct version of the DLL.
I can check the $(MSBuildBinPath) variable against a list of known paths, but that will not work if MSBuild is running from some non-standard location. This is not an elegant solution.
Is there some way to reliably determine whether the currently running MSBuild (or other process hosting the MSBuild engine) is 32-bit or 64-bit?
Have you considered writing a custom MSBuild task that returns bitness of the current process?
See How to detect Windows 64-bit platform with .NET? for an example.
There is a related question at Find out the "Bit"ness of the current OS in MSBuild. In that question there is an answer by Blindy stating:
On a 64-bit OS, the following variables are defined:
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
So just test for ProgramFiles(x86) and if it's empty, use ProgramFiles.

Windows 64-bit registry v.s. 32-bit registry

I heard on Windows x64 architecture, in order to support to run both x86 and x64 application, there is two separate/different sets of Windows registry -- one for x86 application to access and the other for x64 application to access? For example, if a COM registers CLSID in the x86 set of registry, then x64 application will never be able to access the COM component by CLSID, because x86/x64 have different sets of registry?
So, my question is whether my understanding of the above sample is correct? I also want to get some more documents to learn this topic, about the two different sets of registry on x64 architecture. (I did some search, but not found any valuable information.)
I ran into this issue not long ago. The short answer is that if you run a 32 bit application on a 64 bit machine then it's registry keys are located under a Wow6432Node.
For example, let's say you have an application that stores its registry information under:
HKEY_LOCAL_MACHINE\SOFTWARE\CompanyX
If you compile your application as a 64 bit binary and run it on a 64 bit machine then the registry keys are in the location above. However, if you compile your application as a 32 bit binary and run it on a 64 bit machine then your registry information is now located here:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\CompanyX
This means that if you run both the 32 bit and 64 bit versions of your application on the same machine then they will each be looking at a different set of registry keys.
Your understanding is correct. There wouldn't be any need for a x64 app to access the x86 CLSIDs since it could never load those components anyway and vice versa.
If you want to create component for use by both x86 and x64 then you need to either create a pair of dlls one built for x86 and the other for x64 and register both in their appropriate parts of the registry. The regsrv32.exe in the System32 folder will perversely register the x64 component and the regsrv32.exe in the SysWOW64 folder will register the x86 component.
Alternatively build a .NET assembly for Any CPU which can used by either CPU architecture.
They aren't separate registries--one is a subnode of the other, and the OS does virtualization to make sure that 32bit apps get their keys and 64bit apps get their keys.
Here is the Wikipedia article on the WOW64 registry which may give you some of the information you are looking for:
http://en.wikipedia.org/wiki/WOW64
I run an x64 bit machine as my desktop; and I have never run into any issues with the different registry configurations.
Per MSDN, there is apparently a difference:
http://msdn.microsoft.com/en-us/library/ms724072(VS.85).aspx
HTH
How to register .NET assembly to be used as COM in pure 64-bit application?
Problem:
By default, if you enable "Register for COM Interop" in build settings, it DOES NOT register type library for 64-bit.
Solution:
To register your assembly which is not in GAC on a 64-bit machine, open cmd window and do:
cd c:\windows\microsoft.net\framework64\v2.x.xxxxx
regasm /codebase "path to your compiled assembly dll"
This will eliminate "Class Not Registered Error" when using native C++ to instanciate .NET assembly as COM object.