WIX CustomAction loading CLR 4.0 instead of 2.0 - wix

I'm trying to write a c# custom action and using .Net 2, however I can't seem to get things to work. I believe the MSI is using the wrong CLR version. I see this in the log file a few lines above where the MSI is calling my CA (line line does not appear if I comment out my CA):
SFXCA: Binding to CLR version v4.0.30319.
My custom action does not appears to load (assuming since I do not see any of the logging messages). I am using Wiz 3.6.3014.0. Is this supported or does the Windows Installer just use the latest runtime available on the machine?
Thanks

When you use WiX to create a C# custom action project, it by default creates an XML file called CustomAction.config. The purpose of this file is to instruct sfxca.dll what version of the CLR to use when running your code. The default implementation of this file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<!--
Use supportedRuntime tags to explicitly specify the version(s) of the .NET Framework runtime that
the custom action should run on. If no versions are specified, the chosen version of the runtime
will be the "best" match to what Microsoft.Deployment.WindowsInstaller.dll was built against.
WARNING: leaving the version unspecified is dangerous as it introduces a risk of compatibility
problems with future versions of the .NET Framework runtime. It is highly recommended that you specify
only the version(s) of the .NET Framework runtime that you have tested against.
Note for .NET Framework v3.0 and v3.5, the runtime version is still v2.0.
In order to enable .NET Framework version 2.0 runtime activation policy, which is to load all assemblies
by using the latest supported runtime, #useLegacyV2RuntimeActivationPolicy="true".
For more information, see http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
-->
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727"/>
</startup>
<!--
Add additional configuration settings here. For more information on application config files,
see http://msdn.microsoft.com/en-us/library/kza1yk3a.aspx
-->
</configuration>
Basically it's a good practice for CA's written in .NET 2.0/3.0/3.5 ( all CLR 2.0 ) to be allowed to run against 4.0 because you could come across a machine that has only 4.0 installed. Generally your code should work against 4.0 and if it doesn't, I'd fix that.
Alternatively you could update the config file to only allow running on 2.0 and then put the needed checks into the installer to make sure that this version of the CLR is infact installed.

Related

Can we use .Net 4.0 framework in the Visual Basic Interop form?

I'm having a project which is to add new features to a VB6 application. In order to migrate the application to the more advanced technology incrementally, we choose to use VB Interop technology. However, we found that the VB Interop Form is actually based on .Net 2.0. So, I'm asking how can we use higher version of the .Net framework?
thanks
Short answer is no, but stable in 3.5 framework. Microsoft is aware of the issue, but can't tell you when there would be a fix. You can find more here.
Another good read here.
Interop Forms Toolkit can be used with .NET 4.0. I have been using it for more than 6 months with no problems.
The problem discussed here is due to In-Process Side-by-Side Execution, introduced in .NET 4. With this you can have different versions of the CLR running in your application. This can be fixed by using an app.config file:
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
</configuration>
I answered a similar problem here, and here

System.Data.SQLite BadImageFormatException with NHibernate, works finewhen standalone

I tried to use NHibernate with SQLite,
version=1.0.74.0 for .NET 4 and 32 bit.
I use a 64bit WIN7, but build the application in x86 mode
(default in VS2010 express).
When I use the same SQLite as a standalone application it works fine, but when
I try to use it with NHibernate it throws BadImageFormatExcepion
I debugged a bit NHibernate and the Exception is thrown at the folllowing statement
System.Type.GetType("System.Data.SQLite.SQLiteConnection, System.Data.SQLite");
Any chances somebody knows the solution?
Is it because I use default mode in VS Express?
Do I need to specify platform using some other method?
try to download some other dll for sqlite?
I checked some other answers on SO thebest I got was
to add to my app.config this:
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SQLite"/>
<add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"/>
</DbProviderFactories>
</system.data>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
If VS express does not allow you to choose a platform you can try setting it up manually in .csproj file
<PlatformTarget>x86</PlatformTarget>
After building your app make sure that:
it is executed as 32 or 64 bit app depending on what you put in PlatformTarget (using Windows Task Manager or Process Explorer)
the right version of SQLite.Interop.dll is copied to the folder where you have your exe (this dll is platform dependent, so you need to copy the version corresponding to EXE platform)
Corresponding version of Visual C++ 2010 SP1 Redistributable Package is installed
Also try removing useLegacyV2RuntimeActivationPolicy from config.
From BadImageFormatException doc:
... A DLL or executable is loaded as a 64-bit assembly, but it contains
32-bit features or resources. For example, it relies on COM interop or
calls methods in a 32-bit dynamic link library. ... To address this exception, set the project's Platform target property to x86 (instead of x64 or AnyCPU) and recompile.

How do I set the .NET Framework version used to run a MSIExec Custom Action

I am using WiX to create a MSI that calls a managed Custom Action (CA) written with Votive in VS 2008. The CA targets .NET 32 bit Framework 3.5. When I run the setup it fails loading the CA since it cannot find the right framework version. In the MSI installation log are the lines
MSI (s) (5C:C0) [10:25:00:680]: Hello, I'm your 32bit Impersonated custom action server.
SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI34ED.tmp-\
SFXCA: Binding to CLR version v4.0.30319
I have worked out that the issue is the wrong framework version is being loaded. It seems to be the inverse problem mentioned when trying to run a version 4 CA and version 2 of the framework is loaded by MSIExec (I assume it is the MSIExec that decides to load the framework).
I have VS 2010 installed on the box as well, but for reasons beyond my control I must use VS 2008 for the project. If I upgrade the project to VS 2010 everything runs as expected, since the CA is then targeted to .NET 4.0.
Is there some way I can get MSIExec to load .NET 2.0/3.5 when calling the Custom Action?
UPDATE: I have changed the CustomAction.config so that it now has
<!--<supportedRuntime version="v4.0" />-->
<supportedRuntime version="v2.0.50727"/>
and it has made no difference.
I have also found that it is the act of trying to load the CA into the debugger that is causing the exception. If I run the msi without breaking on the method, it runs as expected (no errors). SO I can deploy the setup as a .NET 3.5 setup, I just cannot debug the CA.
It looks like you cannot override the version of .Net used by MSIExec.
Aaron Stebner's blog entry Don't use managed code to write your custom actions! says:
Also, if you author a managed DLL custom action you leave your fate in the hands of Windows Installer, because it will use the latest version of the .NET Framework on the machine in all cases

app.config "forced" (?) on .net 4.0.. is it needed?

It seems that when upgrading a project to .net 4.0 in VS 2010 Beta 2,
a app.config file is generated, which roughly looks like this:
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Is this file needed in case I want to have a .NET 4.0 only executable?
NOTE: Interestingly enough, this only happens in c# as opposed to f# projects.
I have successfully removed it without any visible (so far) side effects.
Can anyone elaborate on it's importance (if at all)
It's not so much about how the app behaves on your computer, but how it will behave on other computers, or when you install an updated dotnet runtime on your machine.
Basically, if you don't include this, the latest version of the dotnet runtime will be used to run your app. That might sound like a good thing, until some feature that you depend on becomes deprecated or a bug that you don't realize you're depending on gets fixed.
More usefully, when you have originally built an app to work with an older version of the dotnet framework, you can use this feature after you've tested it with newer versions to assert that, yes, it does work with the latest version.
Here's the horse's mouth text from MSDN:
If the version of the .NET Framework
that the application was built against
is present on the computer, the
application runs on that version.
If the version of the .NET Framework
that the application was built against
is not present and a configuration
file does not specify a version in a
Element, the
application runs on the latest version
of the .NET Framework that is present
on the computer.
If the version of the .NET Framework
that the application was built against
is not present and the configuration
file specifies a version in a
Element, the
application runs on the latest version
that is specified in the application
configuration file and is present on
the computer.

How can I target .Net 4.0 Beta using NAnt?

I want to start testing my project using the Microsoft .Net 4.0 Beta version that has already been released. I know that adding a "net-4.0" target framework to NAnt requires updating nant.exe.config file, does anyone know what are the necessary changes?
If you want to use nant to build projects targeting .NET 4.0 you'll have to modify NAnt.exe.config and add the net-4.0 target framework and add a <supportedRuntime ... /> line to the <startup> section.
http://paigecsharp.blogspot.com/2009/08/nant-net-framework-40-configuration.html is a full code for .config file for NAnt.