This project has moved. For the latest updates, please go here.

InstallUtil cannot install selfhosted WebApi when using CORS libraries (nuGet version 5.2.2.0)

Sep 10, 2014 at 12:17 PM
I created a Windows Service Project containing a self hosted WebAPI using CORS. The WebApi works perfectly as when self-hosting it inside a console application. But brought to a Windows Service project it fails to be installed. There seems to be a problem when InstallUtil tries to resolve the references for Microsoft.Owin.Cors. It has a reference to System.Web.Cors, as of version 5.0.0.0 and even if it's defined as not version specific a reference to System.Web.Cors version 5.2.2.0 produces an error. The CORS libs were installed from the according nuGet-packages (5.2.2.0)

Btw: An explicit binding redirect defined in the app.config didn't solve the problem.

I've got only the german log text produced by the Assembly Binding Log Viewer when running the InstallUtil-Tool but I think this underlines my assumption ...
*** Protokolleintrag für Assembly-Binder  (10.09.2014 @ 14:00:35) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80070002. Das System kann die angegebene Datei nicht finden.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt.  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = InstallUtil.exe
Aufruf von Assembly : Microsoft.Owin.Cors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: Diese Bindung startet im LoadFrom-Load-Kontext.
WRN: Das systemeigene Image wird nicht im LoadFrom-Kontext durchsucht. Das systemeigene Image wird nur im Standard-Load-Kontext durchsucht, z. B. Assembly.Load().
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Die Suche im GAC war nicht erfolgreich.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors.DLL.
LOG: Die Assembly wurde erfolgreich heruntergeladen. Datei-Setup wird begonnen: C:\Users\ferimisee\Documents\SharpDevelop Projects\WebService3\bin\Debug\System.Web.Cors.dll.
LOG: Die von der Quelle ausgeführte Setup-Phase beginnt.
LOG: Der Assemblyname ist: System.Web.Cors, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
WRN: Der Vergleich des Assemblynamens führte zum Konflikt: Nebenversion.
ERR: Der Assemblyverweis entsprach nicht der gefundenen Assemblydefinition.
ERR: Die von der Quelle ausgeführte Setup-Phase schlug mit hr = 0x80131040 fehl.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors/System.Web.Cors.EXE.
LOG: Fehler bei allen Such-URLs.

*** Protokolleintrag für Assembly-Binder  (10.09.2014 @ 14:00:35) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80070002. Das System kann die angegebene Datei nicht finden.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt.  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = InstallUtil.exe
Aufruf von Assembly : Microsoft.Owin.Cors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: Diese Bindung startet im LoadFrom-Load-Kontext.
WRN: Das systemeigene Image wird nicht im LoadFrom-Kontext durchsucht. Das systemeigene Image wird nur im Standard-Load-Kontext durchsucht, z. B. Assembly.Load().
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Die Suche im GAC war nicht erfolgreich.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/System.Web.Cors/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors.DLL.
LOG: Die Assembly wurde erfolgreich heruntergeladen. Datei-Setup wird begonnen: C:\Users\ferimisee\Documents\SharpDevelop Projects\WebService3\bin\Debug\System.Web.Cors.dll.
LOG: Die von der Quelle ausgeführte Setup-Phase beginnt.
LOG: Der Assemblyname ist: System.Web.Cors, Version=5.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
WRN: Der Vergleich des Assemblynamens führte zum Konflikt: Nebenversion.
ERR: Der Assemblyverweis entsprach nicht der gefundenen Assemblydefinition.
ERR: Die von der Quelle ausgeführte Setup-Phase schlug mit hr = 0x80131040 fehl.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors/System.Web.Cors.DLL.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors.EXE.
LOG: Herunterladen von neuem URL file:///C:/Users/ferimisee/Documents/SharpDevelop Projects/WebService3/bin/Debug/System.Web.Cors/System.Web.Cors.EXE.
LOG: Fehler bei allen Such-URLs.

*** Protokolleintrag für Assembly-Binder  (10.09.2014 @ 14:00:35) ***

Fehler bei diesem Vorgang.
Ergebnis der Bindung: hr = 0x80070002. Das System kann die angegebene Datei nicht finden.

Der Assemblymanager wurde geladen aus:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Als EXE-Datei ausgeführt.  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe
--- Ein detailliertes Fehlerprotokoll folgt. 

=== Zustandsinformationen vor Bindung ===
LOG: DisplayName = System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
 (Fully-specified)
LOG: Appbase = file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/
LOG: Ursprünglicher PrivatePath = NULL
LOG: DynamicBase = NULL
LOG: CacheBase = NULL
LOG: AppName = InstallUtil.exe
Aufruf von Assembly : Microsoft.Owin.Cors, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
===
LOG: Diese Bindung startet im LoadFrom-Load-Kontext.
WRN: Das systemeigene Image wird nicht im LoadFrom-Kontext durchsucht. Das systemeigene Image wird nur im Standard-Load-Kontext durchsucht, z. B. Assembly.Load().
LOG: Die Anwendungskonfigurationsdatei wird verwendet: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe.Config
LOG: Die Hostkonfigurationsdatei wird verwendet: 
LOG: Die Computerkonfigurationsdatei von C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config wird verwendet.
LOG: Verweis nach der Richtlinie: System.Web.Cors, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
LOG: Die gleiche Bindung ist bereits aufgetreten und hat den Fehler hr = 0x80070002 verursacht.
ERR: Nicht behebbarer Fehler während der Prüfung vor dem Herunterladen (hr = 0x80070002).
Coordinator
Sep 10, 2014 at 4:38 PM
Can you share the binding redirect you added?

Console projects add binding redirects for you automatically, but service projects do not.
Sep 11, 2014 at 6:38 AM
Hi Tratcher,

the binding redirect was added like so:
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Cors" publicKeyToken="31bf3856ad364e35" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
Coordinator
Sep 11, 2014 at 10:30 PM
Ok, that looks right. Maybe the config file isn't in the right place to be picked up? What happens if you add syntax errors, does it throw?
Sep 12, 2014 at 6:47 AM
I added some syntax errors to the .config which is in the same place (directory) as the .exe. The problem stays the same and no exceptions were thrown but the one mentioned. The InstallUtil.exe is called from within a CMD shell and the current directory is the bin directory of my service .exe ...
Sep 12, 2014 at 11:45 AM
Edited Sep 12, 2014 at 11:50 AM
@MiSeeger: Tratcher's suggestion will work... if you add the binding redirects in %WinDir%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe.config.
It's terribly not convenient, but AFAIK, it's the only way to make it work OTB.

https://connect.microsoft.com/VisualStudio/feedback/details/525564/installutil-exe-does-not-honor-app-config-especially-binding-information

That said, you have two alternatives:
  • Solution 1: you can embed InstallUtil.exe and InstallUtil.exe.config in your app. This way, you don't have to modify the machine-wide InstallUtil.exe.config.
  • Solution 2: you can also provide your own installer based on the same API InstallUtil.exe uses. You'll also have to create a new [yourinstallerfile].exe.config file to add the binding redirects. See this great SO post for more information: http://stackoverflow.com/questions/1195478/how-to-make-a-net-windows-service-start-right-after-the-installation/1195621#1195621
Sep 12, 2014 at 12:25 PM
@PinpointTownes: Solution 1 did the trick! Thanks a lot for this hint. I'll also have a serious look at Solution 2.