views:

392

answers:

4

Update: Last night, I decided that this is just too much work to change the folder where some reports are saved. My work-around here is to rename the folder, run the batch job I need done, and then change the folder name back to what it was originally. I feel like I could spend the rest of today and all of next week working on this and still have nothing to show. I'd rather catch hell for going against my boss than not be able to invoice our customers (which only happens once a year). Thank you to all those who have helped, I'm humbled by your willingness to help some anonymous fella in over his head. I'm not sure how to "abandon" this question but still give you guys props, I'll read the faq and any comments during lunch. Thank you.

I'm trying to debug a c# application that my predecessor created. he's a programmer, I'm a sysadmin, maybe that's where I'm going wrong.

Anyway, I need to recompile one of the assemblies and deploy it to our production server. When I compile it, I get the error:

The type 'Mcrcsip.Web.McrcsipWebExceptionBase is definined in an assembly that is not referenced. You must add a reference to assembly 'Mcrcsip.Web, Version=2.0.3266.28977, Culture=neutral, PublicKeyToken=c3de6c6abcdf794b'.

I happen to have a copy of that assembly, and when I delete the reference to the existing assembly (2.0.0.0 with a different public key token) and add a reference to the assembly it's asking for, when I compile, I get this error message:

The type 'Mcrcsip.Web.McrcsipWebExceptionBase is definined in an assembly that is not referenced. You must add a reference to assembly 'Mcrcsip.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8bbdde85caf008d0'.

If I search for this error on google (genericised, of course) I get a bunch of "this is how you add an assembly reference..." results.

How do I get off this merry-go-round?

Here's how the solution's laid out:

  • Mcrcsip.Amwa.Solution
    • http://amwa-test.internal.lan/
    • Mcrcsip.Amwa.Core
      • Mcrcsip.Aws.Bol
      • Mcrcsip.Common
      • Mcrcsip.Web
      • nunit.framework
      • System
      • System.Configuration
      • System.Data
      • System.Enterprise Services
      • System.Web
      • System.Web.Services
      • System.XML
    • Mcrcsip.Amwa.CrFactory
      • CrystalDecisions.CrystalReports.Engine
      • CrystalDecisions.Enterprise.Framework
      • CrystalDecisions.Enterprise.InfoStore
      • CrystalDecisions.ReportSource
      • CrystalDecisions.Shared
      • CrystalDecisions.Web
      • Mcrcsip.Amwa.Core
      • Mcrcsip.Web
      • System
      • System.configuration
      • System.Data
      • System.Drawing
      • System.Web
      • System.XML
    • Mcrcsip.Amwa.PdfFormHandler
      • itextsharp
      • Mcrcsip.Amwa.Core
      • Mcrcsip.Web
      • System
      • System.Configuration
      • System.Data
      • System.Web
      • System.Xml
    • Mcrcsip.Amwa.Web
      • Mcrcsip.Amwa.Core
      • Mcrcsip.Amwa.CrFactory
      • Mcrcsip.Amwa.PdfFormHandler
      • Mcrcsip.Aws.BOL
      • Mcrcsip.Common
      • Mcrcsip.SharePoint
      • Mcrcsip.Web
      • System
      • System.configuration
      • System.Data
      • System.EnterpriseServices
      • System.Web
      • System.Web.Services
      • System.XML
    • Mcrcsip.Amwa.WebControls
      • System
      • System.Data
      • System.Design
      • System.Drawing
      • System.Web
      • System.Xml
    • Mcrcsip.Amwa.Setup
+4  A: 

Reference inconsistencies or: how i learned how to stop worrying and love ILDASM

ahem, cough cough,

Problem

Nick,

From re-reading your original post, it is clear that you have a dll version-inconsistency issue. That is, at least one project in your solution depends on Mcrcsip.Web version X, and at least one project in your solution depends on Mcrcsip.Web version Y [or worse still, depends on a library that depends on Mcrcsip.Web version Y]. These can be difficult and tedious to track down.

See Recommended Solution to skip to the end.

How

This sort of inconsistency arises when

  1. you have a dependency such as A depends on B and C, B depends on C,
  2. A and B are originally built against C ver 1,
  3. A is updated and built against C ver 2,

contrary to what we intuitively expect, B will not auto-magically update to use C ver 2 when we build A. Both A and B must reference the same library to build properly. So either A must conform to C ver 1, or B must be rebuilt and conform to C ver 2.

Now, this can happen in any project configuration, which is why it is important to version your software [believe me this problem gets worse without proper signing\versioning], and communicate well within your team whenever a dependency update occurs.

It is also worth knowing there are two kinds of dependency references, hard and soft [in actual fact, they are the same, that is links to dlls, except one is a special case of the other, and conceptually it helps to distinguish the two].

Hard References

A hard reference is a dependency of a project to a static dll. That is, the dependency was built at a specific time and will never update unless its physical file is replaced with a new one. Hard references are added to a solution via Add References dialog, and adding a reference from the .Net, COM, or Browse tabs. Hard references are typically used to add dependencies to software developed outside the scope of the current solution [ie framework, third party, and other first party products developed by other internal teams]. Hard references also have a tendency to become stale, because they are maintained and updated by their own development stream.

Assume scenario above

  1. you have a dependency such as A depends on B and C, B depends on C,
  2. A and B are originally built against C ver 1,
  3. A is updated and built against C ver 2,

Further, assume A and B are within the same solution

  • SimpleSolution
    • A
      • B [Hard reference]
      • C v2 [Hard reference]
    • B
      • C v1 [Hard reference]

When A is built, you will receive the error you described. A expects an object from C v2, but because B has a hard dependency on C v1, C v1 is loaded into memory first, and a collision occurs. A expects v2 and finds v1. That is your error.

To resolve this situation, you must

  1. Update project B hard reference C v1 to C v2
  2. Force rebuild of project B
  3. Update project A hard reference B to [newly built] B
  4. Force rebuild of A

Soft References

A soft reference is a dependency of a project to another project within the same solution. That is, the dependency is rebuilt every time the entire solution is rebuilt. Soft references are added to a solution via Add References dialog, and adding a reference from the Projects tab. Soft references are typically used to add dependencies to software developed inside the scope of the current solution, they have the primary advantage of propagating changes as they are made to consumers within the same solution. By virtue of this fact, soft references cannot be stale.

[this is a special case of a hard reference, Visual Studio will add a reference that points to the output path of the target project, i believe it also updates this path if the target project changes its output configuration - but a very handy feature that warrants distinction]

Assume scenario above

  1. you have a dependency such as A depends on B and C, B depends on C,
  2. A and B are originally built against C ver 1,
  3. A is updated and built against C ver 2,

Further, assume A and B are within the same solution

  • SimpleSolution
    • A
      • B [Soft reference]
      • C v2 [Hard reference]
    • B
      • C v1 [Hard reference]

When A is built, you will receive the error you described. A expects an object from C v2, but because B has a hard dependency on C v1, C v1 is loaded into memory first, and a collision occurs. A expects v2 and finds v1. That is your error.

To resolve,

  1. Update project B hard reference C v1 to C v2
  2. Force rebuild of A

As you can see, soft references are easier to maintain.

IL DASM [Intermediate Language DisASeMbler]

Now that you know a bit more about references, and project maintenance, how exactly do you ascertain the state of your build? After all, any one of your projects or their dependencies may be inconsistent.

The easy way is to open your build output directory, and inspect the assembly manifest of each and every single dll that your solution produced.

To inspect an assembly's manifest,

  1. open ildasm.exe
    • For VS2010, ildasm is available from shortcut
    • For VS2008 and VS2005, open a Visual Studio Command Prompt, from command line, type 'ildasm'
  2. open a dll,
    • click File -> Open, or
    • press Ctrl-O, or
    • drag and drop your dll into ildasm window
  3. open MANIFEST
    • double click red triangle node labeled MANIFEST
  4. find references to Mcrcsip.Web
    • click Find and enter Mcrcsip.Web into dialog box, or
    • press Alt-F and enter Mcrcsip.Web into dialog box, or
    • manually inspect contents of MANIFEST file
  5. verify version number

This is tedious and painful, but if you encounter a [non-trivial] dll inconsistency error, this is the only way to find it.

Recommended Solution

  1. Ensure your solution is using soft references where applicable,
    • expand Mcrcsip.Amwa.CrFactory
      • expand References
      • remove reference Mcrcsip.Amwa.Core
      • open Add References dialog
      • open Mcrcsip.Amwa.Core from Projects tab
    • expand Mcrcsip.Amwa.PdfFormHandler
      • expand References
      • remove reference Mcrcsip.Amwa.Core
      • open Add References dialog
      • open Mcrcsip.Amwa.Core from Projects tab
    • expand Mcrcsip.Amwa.Web
      • expand References
      • remove reference Mcrcsip.Amwa.Core
      • remove reference Mcrcsip.Amwa.CrFactory
      • remove reference Mcrcsip.Amwa.PdfFormHandler
      • open Add References dialog
      • open Mcrcsip.Amwa.Core from Projects tab
      • open Mcrcsip.Amwa.CrFactory from Projects tab
      • open Mcrcsip.Amwa.PdfFormHandler from Projects tab
  2. Ensure your solution is using fresh hard references where applicable,
    • expand Mcrcsip.Amwa.Core
      • expand References
      • remove reference Mcrcsip.Aws.Bol
      • remove reference Mcrcsip.Common
      • remove reference Mcrcsip.Web
      • open Add References dialog
      • open Mcrcsip.Aws.Bol from Browse tab [always best to specify location]
      • open Mcrcsip.Common from Browse tab
      • open Mcrcsip.Web from Browse tab
    • expand Mcrcsip.Amwa.CrFactory
      • expand References
      • remove reference Mcrcsip.Web
      • open Add References dialog
      • open Mcrcsip.Web from Browse tab
    • expand Mcrcsip.Amwa.PdfFormHandler
      • expand References
      • remove reference Mcrcsip.Web
      • open Add References dialog
      • open Mcrcsip.Web from Browse tab
    • expand Mcrcsip.Amwa.Web
      • expand References
      • remove reference Mcrcsip.Aws.Bol
      • remove reference Mcrcsip.Common
      • remove reference Mcrcsip.SharePoint
      • remove reference Mcrcsip.Web
      • open Add References dialog
      • open Mcrcsip.Aws.Bol from Browse tab
      • open Mcrcsip.Common from Browse tab
      • open Mcrcsip.SharePoint from Browse tab
      • open Mcrcsip.Web from Browse tab
  3. Build

If you still encounter errors at this step, then you know that one or all of

  • Mcrcsip.Aws.BOL
  • Mcrcsip.Common
  • Mcrcsip.SharePoint

shares your dependency on Mcrcsip.Web, and is referencing the old version. If this is the case, then for each hard reference listed above

  1. select a reference
  2. press F4
  3. copy contents from Path property
  4. open file dialog in ildasm
  5. paste into File name
  6. inspect MANIFEST

Make sure you do this for each and every one of the three hard references above. once you identify which subset of those three are referencing the old version of Mcrcsip.Web, you may now find that project, update its hard reference, rebuild it, and then finally update your hard reference, rebuild, and voila. Bob's your uncle.

Phew.

Le fin

PS apologies for verbosity. this isn't a terribly complex problem, but as i am sure you would agree, it involves a lot of detail. i really hope this helps. thanks for your co-operation too :)

PPS btw, i am inferring from your comments that original developer used hard references everywhere [ie even within same solution]. perhaps he had his reasons, but imo, that is ass.

johnny g
this project, mcrcsip.amwa.web is part of the mcrcsip.amwa solution and won't build because of the mcrcsip.web dll (it took me a while to realize that it wasn't referring to itself). since no assembly's created, I can't load it into this program.I did go through the other projects in the solution and make sure they're not referencing the 2.0.0.0 assembly.
Nick
@Nick, would it be possible to update\edit your original question with a breakdown of your solution? i would like to see 1) top of the list, name of solution as appears in Solution Explorer, 2) beneath solution each project that is part of the solution, 3) under each solution-project, the references of that solution project
johnny g
I created a solution and added just the mcrcsip.amwa.web project. I tried all combinations of the assemblies in the GAC, not in the GAC, I just couldn't get it.I did notice that the assembly never appears on the ".NET" tab of the add-reference dialog, but is listed on the .NET Framework 2.0 configuration snap-in and gacutil.exe also finds it.
Nick
[scratches head] "just the mcrcsip.amwa.web project"? you should not be able to do that by virtue of the fact that mcrcsip.amwa.web *depends* on mcrcsip.amwa.core, no? does mcrcsip.amwa.web have a hard reference to mcrcsip.amwa.core? or a soft one? when you open "Add Reference" dialog, anything added from .Net, COM, or Browse tabs generates a hard reference. anything from Projects tab generates a soft reference. Recent is a mix of references added from any and all tabs. Hard references can go stale [your problem]. Soft ones will recompile as you rebuild solution.
johnny g
put all my comment-y goodness in response. please review :S
johnny g
+1 for the trouble.
Dave Van den Eynde
A: 

If you right-click the reference, go to properties, what is "Specific Version" set to? Make sure that it is set to 'True' and the version listed is indeed 2.0.x.

In the properties page, double-check the path. You might have a different version registered elsewhere in your GAC that is getting precedence. Use "gacutil -l " in the command line to get a list of all registered versions of that assembly. If you see duplicates with different keys, use gacutil to nuke the one you don't want.

j0rd4n
specific version is set to "false" if I use "gacutil -l <assembly>" I see that v2.0.0.0 is in there, so I deleted it using the .NET framework 2.0 configuration snap-in and added 2.0.3266.28977. still no dice.I checked other references for this assembly to see if they in turn referenced mcrcsip.web and some do, but they're also set to "specific version" (I presume that means, "don't care about the assembly's version").I tried toggling this option, it had no effect.I also tried deleting the 2.0.3266.x assembly from the gac and recompiling again, still no effect.
Nick
@Nick - So if you re-compile the assembly, re-register it in the GAC, and re-add it as a reference, does the version # look right in the refrence properties?
j0rd4n
Only if I edit mcrcsip.web's AssemblyInfo.cs file to read: [assembly: AssemblyVersion("2.0.3266.28977")] or 2.0.0.0.
Nick
Are you signing the assembly with a strong key?
j0rd4n
the mcrcsip.amwa.web assembly - no. but I am with the mcrcsip.web assembly. all of the previous versions appear to have strong keys as well.
Nick
A: 

Watch the build other under the Batch Build options. This will let you prioritize what assembly to build first, then dependencies shall get their DLL as required in the proper order.

Will Marcouiller
I can't, apparently. I don't have that option on my build menu, and as far as I can tell, I should - http://msdn.microsoft.com/en-us/library/169az28z(VS.80).aspx
Nick