Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not able to use Windows Script Host Object Model in .net 3.5 project

Tags:

c#

.net

I have a C# console application (.Net version 3.5) with following code

static void Main(string[] args)
{
    IWshRuntimeLibrary.WshNetwork aNetworkInstance = new IWshRuntimeLibrary.WshNetwork();
}

When I run the program it is throwing following error.

An unhandled exception of type 'System.BadImageFormatException' occurred in Microsoft.VisualStudio.HostingProcess.Utilities.dll

Additional information: Could not load file or assembly 'Interop.IWshRuntimeLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

I found that the generated interop file Interop.IWshRuntimeLibrary.dll is refering to 4.0.0.0 version of mscorelib.

.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 4:0:0:0
}

If I change the .net version of the project to 4, then it is working fine. Any idea why the Interop.IWshRuntimeLibrary.dll is always refering to version 4 of mscorlib even when I select .net 3.5 in the project?

PS: The same program is working in other systems. The issue is only in one system.

EDIT: Following are the steps I have done.

Create a C# Console application (.Net version 3.5). Add referece to Windows Scribt Host Object model

Add following line in the Main()

static void Main(string[] args)
{
    IWshRuntimeLibrary.WshNetwork aNetworkInstance = new IWshRuntimeLibrary.WshNetwork();
}

When I run the application, it is throwing following exception.

An unhandled exception of type 'System.BadImageFormatException' occurred in mscorlib.dll

Additional information: Could not load file or assembly 'Interop.IWshRuntimeLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.

I am able to build and run the project in other machines. If I copy the Interop.IWshRuntimeLibrary.dll generated in another machine, then also the program is running in my machine. But I am not able to run the program with the Interop.IWshRuntimeLibrary.dll generated in my machine.

I know it is a strange problem. May be I have to reformat my hard disk as you suggested by Hans Passant :(

EDIT: Output of the detailed build

1>  C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\TlbImp.exe C:\Windows\SysWOW64\wshom.ocx /namespace:IWshRuntimeLibrary /machine:X86 /out:obj\x86\Release\Interop.IWshRuntimeLibrary.dll /sysarray /transform:DispRet /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /reference:C:\WINDOWS\assembly\GAC\stdole\7.0.3300.0__b03f5f7f11d50a3a\stdole.dll 
1>  Microsoft (R) .NET Framework Type Library to Assembly Converter 4.0.30319.33440
1>  Copyright (C) Microsoft Corporation.  All rights reserved.
1>  
1>  TlbImp : Type library imported to C:\Users\IC007121\Documents\Visual Studio 2013\Projects\wsherrortest\wsherrortest\obj\x86\Release\Interop.IWshRuntimeLibrary.dll
1>  Resolved COM reference for item "IWshRuntimeLibrary": "obj\x86\Release\Interop.IWshRuntimeLibrary.dll".
like image 897
Shino C G Avatar asked Jun 01 '16 11:06

Shino C G


1 Answers

Visual Studio uses a SDK tool named TlbImp.exe to build COM references import files. The MsBuild task that does that is named ResolveComReference. This task uses an algorithm that tries to find the proper TlbImp version on the machine that builds the project.

In your case as we see it from msbuild diagnostics, it uses the TlbImp from "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools". Unfortunately, this TlbImp builds CLR 4 assemblies. So you need to use another TlbImp. On my machine, it uses it from "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin" which builds CLR 2 assembly. You probably don't have that TlbImp installed on your build machine so the algorithm redirects silently to the newer one (sounds like a bug, I think it should report the problem, but I'm unsure).

To fix this, you can install an older version of Visual Studio or Windows SDK and it should work magically, or you can configure your project to use a proper TlbImp V3.5 if you have it on your machine somewhere (if you don't have it, then you must install something).

Here is how to modify the MsBuild project from Visual Studio:

  • right click on the project node, Unload Project
  • right click on the project node and Edit Project
  • add the following line to your msbuild project file
  • right click on the project node and Reload project
  • rebuild

...
  <PropertyGroup>
    ... other properties ...
    ... <ResolveComReferenceToolPath should point to a directory that contains TLBIMP V3.5
    <ResolveComReferenceToolPath>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin</ResolveComReferenceToolPath>
  </PropertyGroup>
...
like image 103
Simon Mourier Avatar answered Nov 14 '22 23:11

Simon Mourier