glrb
glrb

Reputation: 21

How programmatically build InstallShield msbuild task on win2008 x64?

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?

Upvotes: 2

Views: 2692

Answers (2)

Jakob Wisor
Jakob Wisor

Reputation: 21

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.

Upvotes: 2

Michael Urman
Michael Urman

Reputation: 15905

Yes, the InstallShield build is 32-bit, and correspondingly only installs its MSBuild support to the 32-bit location. Your MSIL project runs as 64-bit on an x64 machine so for now your solution of making your builder x86 is probably the best, although in the future MSBuild itself may work around this.

If at some point you need the 64-bit more than you need the InstallShield MSBuild task, your other recourse would be to use an Exec task with the command line build.

Upvotes: 1

Related Questions