How to set the attribute Win64 to yes or no according to the bit of Windows Operating System? - wix

I use burn to install prerequisites, including the .net framework and vsto runtime. I have to know if I can install these package, so I do some registry search, for example, on 32 bit Windows, the registry of VSTO Runtime is located at HKLM\SOFTWARE\Microsoft\VSTO Runtime Setup, but on 64 bit Windows, HKLM\SOFTWARE\WOW6432Node\Microsoft\VSTO Runtime Setup instead.
In this case, the attribute Win64 of the element RegistrySearch should be set to no on 32-bit Windows, yes for 64-bit Windows.
<util:RegistrySearch
Id="VSTORuntime"
Root="HKLM"
Key="SOFTWARE\Microsoft\VSTO Runtime Setup\v4R\"
Value="VSTORFeature_CLR40"
Variable="VSTORFeature"
Win64="xxxxx" />
Is there a way to set the attribute Win64 of RegistrySearch according to the bit of OS? btw, I know the build-in VersionNT64, but idk how to convert that to yes or no.

Related

Wix RegistrySearch

I have installed wix as a plugin in Visual studio. I am trying to search for if MATLAB Version 9.2 exists on the PC then allow installation or else abort. To achieve this I do like this
<Property Id="MATLABRUNTIMEEXISTS">
<RegistrySearch Id="Matlab_runtime_search"
Root="HKLM"
Key="SOFTWARE\MathWorks\MATLAB Runtime\9.2"
Name =" MATLABROOT"
Win64="yes"
Type="raw"/>
</Property>
<Condition Message="This application requires RUNTIME 9.2. Please install the Matlab runtime 9.2 then run this installer again.">
<![CDATA[Installed OR MATLABRUNTIMEEXISTS]]>
</Condition>
It works fine, and installer is halted when there is no MATLAB on PC. But even after installing MATLAB it stops the installer.
The MATLABROOT key is "REG_SZ" and "C:\Program Files\MATLAB\MATLAB Runtime".
So what I want to test is actually only the presence of MATLABROOT key.
I saw in other questions people are using <util:RegistrySearch>, but I am not able to use that. I receive error "unsupported extension element", even though I have UtilExtension as reference already added.
Could anyone suggest me what I need to do to actually make it work?

Wix per user installer to detect the Visual C++ 2015 Redistributable

I am creating an .msi installer which has to determine whether the Visual C++ 2015 Redistributable is present in the system and if not then interrupt the installation with custom message. The official Wix documentation refers to the actual installation of the VC++ which I do not wish to do as my installer is "per user" , There are couple of others stackoverflow questions which refer to the bundle rather than the .msi http://wixtoolset.org/documentation/manual/v3/howtos/redistributables_and_install_checks/install_vcredist.html.
Wix Burn vcredist, WIX check if VS2015 C++ redistributable is installed , https://gist.github.com/nathancorvussolis/6852ba282647aeb0c5c00e742e28eb48
So I guess the question is, how to efficiently detect the presense of Visual C++ 2015 Redistributable in the per user installer.
The latest supported Visual C++ downloads
Runtime Detection Approaches
I can find a few ways to detect the presence of the Visual C++ Runtime.
Registry
Keys used by the VCRedist installer (see section below)
Keys mentioned in my original answer - grabbed from this old answer
File Presence & Version Check
Check for presence of core runtime files
See separate section below
MSI API
You can detect whether a specific MSI is installed by looking up the product GUID
Reliable, but hard to keep track of all product GUIDs (different versions)
UPDATE: You can also use the upgrade code as described below. It should remain stable across releases and updates (for each major version and potentially between major versions as well).
Fall-Over EXE?
Suggestions are seen to use an EXE depending on the runtime
Launching it and failing means the runtime is not there or broken
Good & Bad - Evaluation: Option 1 seems to be vulnerable since the merge module variant of deploying the runtime might not write these keys. Option 3 might work well, but it is hard to keep track of all GUIDs. Option 4 seems to already have failed based on the newer runtimes removing certain registry keys. Though fixed now, this could resurface.
File Version Presence / Version Check
The more I look at this, the more I start to think that you have to check for the actual files themselves, and potentially for the right file version. The file vcruntime140.dll in the System32 folder (64-bit version) and SysWOW64 folder (32-bit version)? See files list towards bottom here.
Just adding a link for safe-keeping.
How to detect the presence of the Visual C++ 2012 redistributable package?
Redistributing Visual C++ Files
A test VBScript - for test purposes only (scripts are sometimes blocked by anti-virus):
Set fso = CreateObject("Scripting.FileSystemObject")
MsgBox fso.GetFileVersion("C:\Windows\System32\vcruntime140.dll")
You can detect file presence and version using AppSearch in an MSI file.
Below are some other stuff I wrote up, just leaving it in.
VCRedist
It seems the Visual C++ Redistributable Packages (VCRedist_x86.exe, VCRedist_x64.exe) - which is the recommende way to deploy the runtime - checks the following registry key to determine what versions of the runtime is actually installed:
HKLM\SOFTWARE\Microsoft\VisualStudio\<version>\VC\Runtimes\
The sub-keys x86 and x64 seem to all contain an "Installed" value that is set to 1 when the runtime is installed. I would assume - without having had time to test it all - that you then can check:
HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 Installed = 1
HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86 Installed = 1
Merge Module: After a brief check, it looks like these values are not written by the merge modules that can also be used to distribute this runtime. I do not have the time or means to check this properly now.
Astonishingly both version 2015 and version 2017 of the runtime write to the 14.0 key - since they are binary compatible. If the 2017 version is installed, then the VCRedist executable will return an error since no install is needed. Weird indeed. But for your purpose that should be besides the point. Source.
MSI API - Retrieve Product Codes
Mailbag: How to detect the presence of the VC 8.0 runtime redistributable package
Updated VC 8.0 runtime redistributable packages are included in Visual Studio 2005 SP1
How can I find the product GUID of an installed MSI setup?
UPDATE: installer.ProductState - normal installed state is 5:
I forgot about the ProductState property when writing the below.
You can check for an installed product with two lines of code if you
have the actual product code:
Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
MsgBox installer.ProductState("{00000000-0000-0000-0000-000000000001}")
Here is even one more way to do it: MSDN: How to programmatically check for the presence of a Windows Installer-based product by using its product code.
Tip: I wouldn't use this approach seeing as the product code changes frequently when products are updated. Hence I like better to
check for file versions of core-runtime files. This seems more
reliable for the future (provided version parsing is done correctly
and reliably - don't roll your own).
Mockup:
Public installer
Set installer = CreateObject("WindowsInstaller.Installer")
' Don't have the 2015 GUID
VC2015 = CheckForProductCode("{00000000-0000-0000-0000-000000000000}")
VC2017 = CheckForProductCode("{C77195A4-CEB8-38EE-BDD6-C46CB459EF6E}")
MsgBox "VC2015: " & CStr(VC2015) & vbCrLf & "VC2017: " & CStr(VC2017)
Function CheckForProductCode(productcode)
CheckForProductCode = False
For Each product In installer.ProductsEx("", "", 7)
If(LCase(productcode) = LCase(product.ProductCode)) Then
CheckForProductCode = True
Exit For
End If
Next
End Function
Update based on Zett42's suggestion to enumerate products sharing the same upgrade code:
Set installer = CreateObject("WindowsInstaller.Installer")
' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"
' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
For Each u In upgrades
MsgBox u, vbOKOnly, "Product Code: "
Next
Deploying The Visual Studio C++ Runtime
Beyond detection, there are several approaches for distributing the Visual Studio C++ Runtime:
Static Linking
Visual C++ Redistributable Packages
VCRedist_x86.exe, VCRedist_x64.exe, or VCRedist_arm.exe
Program Files(x86)\Microsoft Visual Studio\2017\edition\VC\Redist\MSVC\lib-version
Redistributable Merge Modules (.msm files)
Insufficient for some purposes (The universal CRT):
Redistributables for deploying C++ exe developed with Visual Studio 2015 on Windows 7
WIX merge c++ runtime
Local Application Folder
Copy DLLs to the local application folder
Not recommended for servicing reasons (updates, security fixes)
Links For Safe Keeping:
Redistributables for deploying C++ exe developed with Visual Studio 2015 on Windows 7
How to detect whether I need to install VCRedist?
WIX merge c++ runtime
How to detect if Visual C++ 2017 Redistributable is installed
Old Answer
There is this old post. I am not too fond of direct registry reads, let me see if I can find a more reliable way, but maybe have a look in the mean time: Detect if Visual C++ Redistributable for Visual Studio 2012 is installed
Just one more link, how to find the Windows Installer product code of products that are installed: How can I find the product GUID of an installed MSI setup?
You can use LaunchConditions from WiX Toolset. The detection can be done by RegistrySearch.
Until version 2015 it was just a registry key, GUID value. Since 2017 and still in 2019 the key is concat (merged), so it is not that easy anymore. This is way I used a loop from 21 to 40 to find all places. C++ Runtime Documentation.
Add the following lines to your product.wxs inside the Product elemnent:
...
<!-- Visual C++ Redistributable 2015, 2017 and 2019 (x86) -->
<Property Id="CPPRUNTIME2015X86" Secure="yes">
<!-- C++ 2015 -->
<RegistrySearch Id="mfc140x86_23026" Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\{74d0e5db-b326-4dae-a6b2-445b9de1836e}" Type="raw" />
<RegistrySearch Id="mfc140x86_24215" Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\{e2803110-78b3-4664-a479-3611a381656a}" Type="raw" />
<!-- C++ 2017 -->
<RegistrySearch Id="mfc1416x86" Root="HKCR" Key="Installer\Dependencies\VC,redist.x86,x86,14.16,bundle" Type="raw" />
<!-- C++ 2019 -->
<?foreach CPPRUNTIMEVERSIONPREFIX in 21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40?>
<RegistrySearch Id="mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x86" Root="HKCR" Key="Installer\Dependencies\VC,redist.x86,x86,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle" Type="raw" />
<?endforeach ?>
</Property>
<Condition Message="Microsoft Visual C++ 2015-2019 (x86) Redistributable missing">
<![CDATA[((REMOVE="ALL")) OR Installed]]>
</Condition>
<!-- Visual C++ Redistributable 2015, 2017 and 2019 (x64) -->
<?if $(var.Platform) = x64 ?>
<Property Id="CPPRUNTIME2015X64" Secure="yes">
<!-- C++ 2015 -->
<RegistrySearch Id="mfc140x64_23026" Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\{e46eca4f-393b-40df-9f49-076faf788d83}" Type="raw" />
<RegistrySearch Id="mfc140x64_24215" Root="HKLM" Key="SOFTWARE\Classes\Installer\Dependencies\{d992c12e-cab2-426f-bde3-fb8c53950b0d}" Type="raw" />
<!-- C++ 2017 -->
<RegistrySearch Id="mfc1416x64" Root="HKCR" Key="Installer\Dependencies\VC,redist.x64,amd64,14.16,bundle" Type="raw" />
<!-- C++ 2019 -->
<?foreach CPPRUNTIMEVERSIONPREFIX in 21;22;23;24;25;26;27;28;29;30;31;32;33;34;35;36;37;38;39;40?>
<RegistrySearch Id="mfc14$(var.CPPRUNTIMEVERSIONPREFIX)x64" Root="HKCR" Key="Installer\Dependencies\VC,redist.x64,amd64,14.$(var.CPPRUNTIMEVERSIONPREFIX),bundle" Type="raw" />
<?endforeach ?>
</Property>
<Condition Message="Microsoft Visual C++ 2015-2019 (x64) Redistributable missing">
<![CDATA[((REMOVE="ALL")) OR Installed]]>
</Condition>
<?endif ?>
...

Wix/Burn - condition to not run MSIPackage and thus not uninstall app

I've got myself into a bit of state with a version of my WiX Bootstrapper that is out in the field and am struggling to see how I can get round my problem with the new version.
Basically the version that is out there has a couple of MSIPackage elements that installs SQL CLR & SMO using Mircosoft's standard MSIs (SQLSysClrTypes.msi & SharedManagementObjects.msi) - but unfortunately they are the x64 versions. Now that's fine for 64bit PCs (as our app can use the 64bit version) and so on those PCs all is ok. But obviously when someone tries and installs it on a 32bit machine, it fails.
So, what I'm wanting the new setup.exe to do; is to detect if the 64bit version is installed & it's version (which I do via a Registry search); if it is, then don't do anything (ie don't install the x86 version). Also detect if the x86 version is installed & it's version (again I can do this) - then only install the x86 version; if neither the x86 or the x64 version is installed ( or they are not the correct version - in this case v13.0.1601.5)
My logic for this was:
<util:RegistrySearch Id="IsSMOInstalledx86"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
Value="Version"
Result="value"
Variable="SMOVersionx86"/>
<util:RegistrySearch Id="IsSMOInstalledx64"
Root="HKLM"
Key="SOFTWARE\Microsoft\Microsoft SQL Server\SharedManagementObjects\CurrentVersion"
Value="Version"
Win64="yes"
Result="value"
Variable="SMOVersionx64"/>
and
<MsiPackage SourceFile="$(var.DependenciesPath_Microsoft)\System CLR Types for SQL Server 2016\v13.0.1601.5\SQLSysClrTypes.msi"
Id="SQLCLR"
DisplayName="System CLR Types for SQL Server 2016"
Visible="yes"
InstallCondition="(SMOVersionx86 <> "13.0.1601.5") AND (SMOVersionx64 <> "13.0.1601.5")"
SuppressSignatureVerification="yes"/>
<MsiPackage SourceFile="$(var.DependenciesPath_Microsoft)\Shared Management Objects\v13.0.1601.5\SharedManagementObjects.msi"
Id="SQLSMO"
After="SQLCLR"
DisplayName="Shared Management Objects for SQL Server 2016"
Visible="yes"
InstallCondition="(SMOVersionx86 <> "13.0.1601.5") AND (SMOVersionx64 <> "13.0.1601.5")"
SuppressSignatureVerification="yes"/>
But my problem is that when this is run on a 64bit PC (where SMO is already installed) - the InstallCondition evaluates to FALSE and as the WiX documentation clearly states; if it evaluates to FALSE, then the product is UNINSTALLED - which is obviously not what I want.
There is never a situation that I want the InstallCondition to evaluate to FALSE i.e. I never should uninstall SMO (if for no other reason, than the user may have installed that for a different app to use i.e. not one of ours). I could remove the installCondition and then it would just install the x86 version on both 32bit and 64bit machines - which is fine; but a bit naff.
So, what I want to do in pseudo code, is something like:
If SMOVersionx86 <> "13.0.1601.5" AND SMOVersionx64 <> "13.0.1601.5"
then
call the MSIPackages (with no installcondition or always TRUE) to INSTALL
else
don't call the MSIPackages"
Endif
i.e. if the condition results in FALSE; then I don't want to do anything ... certainly don't want to call the MSIPackages with FALSE, as this would UNINSTALL them.
I've racked my brain with all sorts of ideas, but they all in some circumstances end up with the installCondition evaluating to false and so end up removing SMO. I thought that perhaps I could have some logic that does install the x64 version on a 64bit PC and the x86 version on a 32bit PC, but even then at least one of the MSIPackage's installcondition would evaluate to false and end up removing a version !!
Any help on this would be gratefully received !!
Cheers,
Big Chris.
MsiPackage has a property Permanent that declares whether a package can be uninstalled. Setting it to "yes" will prevent the bundle from attempting to uninstall it.
However, I'm not sure if adding that property to a new bundle will prevent the old bundle from uninstalling it.

Deploying and Registering Com Interop interfaces

I am attempting to deploy my new .net Com visible interfaces. After installation my new .dll could be loaded by my app. There is a requirement to cast one of the interfaces which is not working.
I am harvesting my wix xml with the use of Heat.
"C:\Program Files (x86)\WiX Toolset v3.10\bin\heat.exe" file "MYComConnect.dll" /out "dll_fragment_12_2015.wxs"
"C:\Program Files (x86)\WiX Toolset v3.10\bin\heat.exe" file "MYComConnect.tlb" -scom /out "tlb_fragment_12_2015.wxs"
To know that it is not a coding problem with my .dll I have registered my .dll and .tlb with regasm and everything works fine.
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "MYComConnect.dll" /tlb
I then did a registry comparison of what is added by regasm and what my wix installer adds.
I noticed that the following folders keys were added by regasm but were NOT added by my wix install (corresponding values were also added by regasm but I will not post it all)
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\TypeLib
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\TypeLib
It seems that my wix install only adds registry keys in Wow6432Node. Regasm adds keys to both.
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{721AE779-4A04-4FFE-B317-FE2355DE31FA}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{A001212B-8F67-42B6-BAA6-D61D6B34FC26}\TypeLib
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\ProxyStubClsid32
HKLM\SOFTWARE\Classes\Wow6432Node\Interface\{F293DBB5-471C-4D71-80CB-C3B30EBDFE10}\TypeLib
The other difference I noted is that heat has the following entry for each class whereas Regasm does not have it
HKLM\SOFTWARE\Classes\Wow6432Node\CLSID\{FB1D6314-4409-46E9-BD92-DDD99D110CDE}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}\: ""
I have read that it does not matter where the interfaces are registered as they do not depend on bitness however after a comparison of what regasm does and what heat harvests it appears that if the interfaces are not added to both the x64 and x32 registry then it does not work.
Just the first RegistryValue element from my heat harvested interface fragment looks like this below. This adds the element to the Wow6432Node.
<Fragment>
<DirectoryRef Id="MYAPPCOMINTEROP">
<Component Id="Com_Interop_TLB" Guid="{F8F60B35-0270-4569-8F0F-9D09398C72D8}">
<File Id="fil460187E36ECD90A7A9A00591ADB1C5CB" Name="MYComConnect.tlb" KeyPath="yes" Source="..\..\MYComConnectReferencedDLL\MYComConnect.tlb" />
<RegistryValue Root="HKCR" Key="Interface\{6D8A24A9-9723-4934-9852-D8877BBBB9F6}" Value="_MYAppConnect" Type="string" Action="write" />
So in the absence of another solution I want to follow what regasm does with the registry entries, how can I achieve that with my Wix xml.
Edit - Further information
Target computer is Win 7 x64 with Office 2010 x86
My Main App has Target CPU x86
Com Visible .dll Target CPU is AnyCPU (the dll is used by Office and my App)
MSI is x64 (as I already have a context menu .dll which needs to write registry items to x64 so that Windows' x64 Explorer will read them.
I hope this does not complicate things but what my COM Visible dll does is allows me to call code in a VSTO addin. I dont think this code is necessary as I can get my custom object from Office and cast it to my custom interface with no problems if I use regasm to register my .dll and create the tlb file.
I actually unregistered everything on my development PC and installed my final MSI. My .dll works and I can cast my interface. What assumptions can I make from this? I am assuming that the problem lies with my Com .dll and building it and thus my problem has nothing to do with my heat harvesting and wix xml coding.
Update 2 of Problem
I obtained a second PC with Visual Studio on it. I Copied my Com .dll project on it and built it. I Created the .tlb file with Tlbexp.exe on this PC. I then installed this with my MSI and I can now cast the COM interface.
So I now have to work out why building it on one PC it works and on another it does not. The most major difference right now is that the PC that works has Win 7 on it, the one that does not work is Win 10.
It might help to know the bitness of your app and your MSI build(s).
A 32-bit app will have a 32-bit registry view, and will need CLSID references to 32-bit COM dlls. Interface entries may refer to a ProxyStub CLSID that will also need to be 32-bit and that means that the interface entries have bitness. That's my understanding anyway, so your COM Dll needs CLSID and Interface references in HKCR (HKL\Software\Classes) in both native and 32-bit WoW6432 if it has both 64 and 32-bit callers.
In WiX, you'd add Win64=yes to the component to make it 64-bit. If you have 32 and 64-bit callers to your COM, then in a 64-bit MSI you'd add both 32 and 64-bit components for your COM, and in a separate 32-bit MSI just the 32-bit components. Heat doesn't know the bitness of your final MSI, so it's up to you to use Win64 on components to target the required registry view.

Should the WIX UpgradeCode be different between an x64 and an x86 version of a product?

I'm assuming YES.
I have an installer for the x86 version, I'm building the installer for the x64 version.
I'm trying to figure out the gotchas. So far it looks pretty straightforward. I feel like they ought to be different UpgradeCodes. I'll need to check for the VersionNT64 property within a Condition to validate the install.
<Condition Message="This package can be installed only on an x64 version of Windows.">
VersionNT64
</Condition>
Any other hints?
I would go ahead and say that yes you should probably have different upgrade codes for the two installers unless you have a specific need for them to be the same.
One scenario I can think of where matching upgrade codes may be useful is if you have previously shipped only a x86 version that was able to install on both 32-bit and 64-bit operating systems. In such a case, having a x64 version with the same upgrade code would allow you to easily handle upgrades from the older x86 to the new x64 version on 64-bit operating systems.
Edit:
I forgot to mention that you can also use the "Msix64" property to determine bitness. It's also unnecessary to add an install condition to the x64 version, since attempting to install it in a 32-bit OS will result in an error message from the Windows Installer service.
Currently I only use one condition in the x86 version of the installer
<Condition Message="You are attempting to install the x86 version in a 64-bit OS">NOT Msix64</Condition>
From my recall I can say that the code for the x86 version would be based on the code used on some 80x86 and later processors for the 16 to 32bit versions while the x64 would be different code for the 64 bit implementation asssuming it is x64 and not IA-64 or Intel64 code. The loader would be different and you may need to check the status of values in the BIOS (if present) and some environment variables to determine if 32 or 64bit mode is in operation on a computer, including the one you are developing the loader on if it supports one or both of the modes.