Get Binder Variables for Assemblies without Installing into the GAC

Heath Stewart

Binder variables in WiX are variables that are resolved, coincidentally, at bind time. This is when the linker, light.exe, collects file information, assigns auto-GUIDs, and generates the output packages among other things. There are binder variables for all versioned binaries, and binder variables specific to both managed and native assemblies or exclusive to one or the other.

The format for using binder variables follows a similar patter to preprocessor variables – variables resolved before compile time – but use a different prefix as shown below.


Managed assemblies will cause the generation of the following list of binder variables, but only if you set the File/@Assembly attribute to “.net”. By default, however, this will cause Windows Installer to install your assembly into the Global Assembly Cache (GAC).

Example usage Example value
!(bind.assemblyCulture.MyAssembly) neutral
!(bind.assemblyFullName.MyAssembly) MyAssembly, Version=, Culture=neutral, PublicKeyToken=0123456789abcdef, ProcessorArchitecture=MSIL
!(bind.assemblyName.MyAssembly) MyAssembly
!(bind.assemblyProcessorArchitecture.MyAssembly) MSIL
!(bind.assemblyPublicKeyToken.MyAssembly) 0123456789abcdef

Because WixPSExtension.dll automatically uses a binder variable to get the assembly name for more easily managed builds, you have to set the File/@Assembly attribute to “.net”. I originally wrote this extension for installing PowerShell snap-ins – as opposed to using a managed custom action as recommended in the PowerShell developer guide which does nothing more than write registry values – so I figured it was time for me to use it for my own Windows Installer PowerShell Extension but I didn’t want this assembly in the GAC.

Peter Marcu recommended I set the File/@AssemblyApplication attribute to the File/@Id for the same file as a workaround. I had considered that previously, but it seemed too odd to work. It turns out, however, this approach does work and in hindsight makes sense. Because the component key path will still resolve to the path as laid out by the Directory table and any type 35 and type 51 custom actions, that component directory is where a private assembly would be installed. The binder still collects all the assembly information about the file, but you can use the file itself to install the assembly as a private assembly.

So, to get binder variables for assemblies without installing into the GAC set File/@Assembly to “.net” or “win32”, then for the same file set File/@AssemblyApplication to the value for File/@Id.


Discussion is closed.

Feedback usabilla icon