How programmatically build InstallShield msbuild task on win2008 x64

64-bitinstallshieldmsbuild

I have a problem using MSBuild and InstallShield on Win 2008 Server x64. I tried to build InstallShield project using MSBuild task which InstallShield team provided and they works well if I run msbuild from C:\Windows\Microsoft.NET\Framework\3.5\ but when I try to run it from C:\Windows\Microsoft.NET\Framework64 \3.5\ I`ve got an error:

The "InstallShield.Tasks.InstallShield"
task could not be loaded from the
assembly c:\Program Files
(x86)\MSBUILD\InstallShield\2009\InstallShield.Tasks.dll.
Could not load file or assembly
'file:///c:\Program Files
(x86)\MSBUILD\InstallShield\2009\InstallShield.Tasks.dll'
or one of its dependencies. An attempt
was made to load a program with an
incorrect format. Confirm that the
declaration is correct,
and that the assembly and all its
dependencies are available.

And it will be ok to use 'usual' Framework path instaed of x64 path but unfortunatly I need to use MSBUILD programmatically using its engine,
and it returns only 2 toolsets, one for 2.0 version Of Framework and one for 3.5. But both located under Framework64 path…I tried to Add My own Toolset with the path to the 'usual' Framework directory. I tried to do it via registry and programmaticaly but it did not work – DefaultToolsVersion was set to my own value, Path looks to the Framework, Toolset with my version was added to the toolsets collection.But for some reason I still get the same message.
The code which is build project:

        Project project = new Project(engine);
        //Toolset customToolset = new Toolset("4.0", @"c:\windows\Microsoft.Net\Framework\v3.5\");
        //engine.Toolsets.Add(customToolset);
        //engine.DefaultToolsVersion = "4.0";

        project.Load(args[0]);

        MSBuildLogger logger = new MSBuildLogger();
        engine.RegisterLogger(logger);

        bool res = engine.BuildProjectFile(args[0]);

Anyone has ideas what should I do to make it work?


It seems that I solved the problem to compile my app with for x86 Platform not AnyCPU…. But may be there is another solution?

Best Answer

The root of your problem is that the assembly Macrovision.InstallShield.Tasks.dll is type-unsafe (managed and native code mixed / IJW) and runs for x86 architecture only. Macrovision has failed here to do nice interop assembly modularisation for specific architectures. Tasks in Macrovision.InstallShield.Tasks.dll depend on native tools to build an MSI package. These native tools are only available for x86 architecture, hence the dependency.

Macrovision should have made a type-safe (AnyCPU / PURE) tasks assembly for MSBuild and deploy architecture specific code and calls into interop assemblies for specific architectures, most prominently x86 and AMD64. This way, any flavor of MSBuild or any other consumer of the tasks assembly would work (of course, as far as specific interop assemblies for a given architecture exist).

Probably the best way to get around your problem is to compile your project as AnyCPU and execute a 32-bit MSBuild. Or start a 32-bit CLR or process and then consume Macrovision's assembly.