View Full Version : CLR Version for Custom Actions

11-08-2010, 12:22 PM
I'm new to install shield an i am encountering some trouble. I have a Basic MSI project set up and a .NET installer class set up to run my install/commit/rollback/uninstall custom actions. That part is working fine. In my install custom action, i reference the SQL Server SMO assemblies to do some database stuff. These assemblies are throwing the following exception:

Microsoft.SqlServer.Management.Smo.FailedOperationException was unhandled by user code
Message=ExecuteNonQuery failed for Database 'master'.
at Microsoft.SqlServer.Management.Smo.Database.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)
at Microsoft.SqlServer.Management.Smo.Database.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
at Microsoft.SqlServer.Management.Smo.Database.ExecuteNonQuery(String sqlCommand)
at * custom code removed *
at System.Configuration.Install.Installer.Install(IDictionary stateSaver)
at System.Configuration.Install.AssemblyInstaller.Install(IDictionary savedState)
at System.Configuration.Install.ManagedInstallerClass.InstallHelper(String[] args)
InnerException: System.IO.FileLoadException
Message=Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Reflection.Assembly.GetType(String name, Boolean throwOnError)
at Microsoft.SqlServer.Management.Common.ServerConnection.GetStatements(String query, ExecutionTypes executionType, Int32& statementsToReverse)
at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)
at Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQuery(StringCollection queries, ExecutionTypes executionType)
at Microsoft.SqlServer.Management.Smo.Database.ExecuteNonQuery(StringCollection sqlCommands, ExecutionTypes executionType)

It looked like it was running my installer class in the 4.0 framework even though the project is targeting the 2.0 framework. Whenever i throw a debug message box in my install method to output the .net framework version (using System.Environment.Version), it does indeed say I am running in the 4.0 framework.

I took a look at the following pages:

Those pages seem to indicate that i can control which version of the .NET framework my installer class runs in. I tried setting the IS_CLR_VERSION property in the install shield project to v2.0.50727. I tried passing the property in to the MSI. I tried adding the property to the custom action data I pass to my MSIs (in addition to the previous settings). Nothing seems to work and my debug message box continues to tell me i am running in the 4.0 framework.

Anybody have any ideas?

11-08-2010, 05:18 PM
I believe there should be some information logged into the verbose Windows Installer Log file related to what it's choosing. You identified the steps correctly in that you would indeed to add something like IS_CLR_VERSION=v2.0.50727 to the custom action data value for any deferred (including rollback and commit) actions, whereas you can specify it directly in the IS_CLR_VERSION property for immediate actions. One thing to note, because it's not so clear in the help articles you link to, is that specifying CustomActionData for deferred actions means setting a property with the same name as the deferred custom action, sometime before the custom action itself is scheduled.

11-08-2010, 05:51 PM
I looked through the MSI log, i didn't find anything incredibly useful looking, but then again, i don't know exactly what i'm looking for either. I do see that the IS_CLR_VERSION property is getting properly set and it is being passed to my custom actions. I'm not really familiar with the term "deferred actions". I just set the .NET Installer class setting to "Yes" on my component containing my .NET installer class and its custom actions are kicked off during the install.

11-10-2010, 11:38 AM
If you're using Installer Classes instead of creating and scheduling custom actions, then this advice does not apply. If you're using our managed code custom action type (which is different from an Installer Class), you should look for the name of your custom action in the log file and check for further debugging output near one of the places that name shows up.

11-15-2010, 09:06 AM
So i changed the installshield options for the .NET framework file locations to point to the 2.0 framework folder (rather than the 4.0 it defaulted to). After that, my custom actions started running in the 2.0 framework. Unfortunately, this seemed like a system wide setting and not a project level setting. I have other products that i'd like to use the 4.0 framework for. It looked like modifying this setting updated the _isconfig.xml file in the project directory. The approach i'm going with which seems to work so far... is to remove the existing _isconfig.xml file from the support files section, copy the _isconfig.xml to a different location (that hopefully won't be updated automatically) and add the _isconfig.xml from the new location to the support files directory. In a simple test or two, it seemed to work.

contents of my _isconfig.xml
<?xml version="1.0"?>
<supportedRuntime version="v2.0.50727"/>