The problem
I have created a build definition in TFS that successfully builds my Azure project and deploys it to the cloud. This build definition is run nightly for continuous deploy.
After the CD build runs and deploys the project, I can't use my application. When I try to load the Index page (or any page), I get the error:
Could not load file or assembly 'Microsoft.WindowsAzure.Diagnostics.StorageUtility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
When I publish my project from Visual Studio, I do not get that error. The application works fine.
I'm trying to find out what TFS is doing differently that causes this error.
Differences between Visual Studio's output files and TFS's output files
There are big differences between the output directory that Visual Studio creates, and the drops directory that TFS creates.
After I package my project in Visual Studio, I can open the \obj\Release directory in my Azure project to look at the build output. Inside that directory, there is a folder for each of the 9 different roles in my project. Each role has copies of all of the Azure assemblies it needs, as well as its app.config file and other referenced DLLs, all sandboxed in its folder.
When I opened the TFS Drops directory, I expected there to be a folder for each of my roles like in Visual Studio. Instead, there was build output from all of my roles mashed together into one directory.
There are copies of the Microsoft.WindowsAzure.Diagnostics.StorageUtility assembly in each of the role folders in my Visual Studio output directory, as well as in the TFS drops directory. All of these copies of this assembly are identical. They all have assembly version 1.0.0.0.
However, the TFS drops folder only contains one app.config file: the one from one of my role projects. It looks like the build output from each role project is copied into the same folder, and the projects overwrite each other's build output.
I don't know if TFS deploys what's in the Drops directory, or if it deploys from somewhere else and merely copies files to the drops directory.
If TFS deploys from the Drops directory, then this is definitely a problem.
If TFS doesn't use the Drops directory to deploy to Azure, then all this may be a red herring.
Assembly binding logging
I turned on assembly binding logging on my web roles using fuslogvw.
The error it shows is:
=== Pre-bind state information === LOG: User = NT AUTHORITY\NETWORK SERVICE LOG: DisplayName = Microsoft.WindowsAzure.Diagnostics.StorageUtility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (Fully-specified) LOG: Appbase = file:///E:/sitesroot/0/ LOG: Initial PrivatePath = E:\sitesroot\0\bin LOG: Dynamic Base = D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\59a01799 LOG: Cache Base = D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\59a01799 LOG: AppName = 5b6b1a2 Calling assembly : Microsoft.WindowsAzure.Diagnostics, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35. === LOG: This bind starts in default load context. LOG: Using application configuration file: E:\sitesroot\0\web.config LOG: Using host configuration file: D:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet.config LOG: Using machine configuration file from D:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config. LOG: Post-policy reference: Microsoft.WindowsAzure.Diagnostics.StorageUtility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 LOG: GAC Lookup was unsuccessful. LOG: Attempting download of new URL file:///D:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/59a01799/5b6b1a2/Microsoft.WindowsAzure.Diagnostics.StorageUtility.DLL. LOG: Attempting download of new URL file:///D:/Windows/Microsoft.NET/Framework64/v4.0.30319/Temporary ASP.NET Files/root/59a01799/5b6b1a2/Microsoft.WindowsAzure.Diagnostics.StorageUtility/Microsoft.WindowsAzure.Diagnostics.StorageUtility.DLL. LOG: Attempting download of new URL file:///E:/sitesroot/0/bin/Microsoft.WindowsAzure.Diagnostics.StorageUtility.DLL. LOG: Assembly download was successful. Attempting setup of file: E:\sitesroot\0\bin\Microsoft.WindowsAzure.Diagnostics.StorageUtility.dll LOG: Entering download cache setup phase. LOG: Assembly Name is: Microsoft.WindowsAzure.Diagnostics.StorageUtility, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 WRN: Comparing the assembly name resulted in the mismatch: Major Version ERR: The assembly reference did not match the assembly definition found. ERR: Setup failed with hr = 0x80131040. ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
I navigated to E:\sitesroot\0\bin and confirmed that the DLL there has assembly version 2.1.0.0
But like I said, in the TFS drops folder the DLL has assembly version 1.0.0.0.
Where could this 2.1.0.0 DLL be coming from?