I haven’t played around enough with Visual Studio 2005 to know if this issue is resolved, but I hope it is. This is becoming more and more of a pain for me, although I think I finally have figured out the root cause (which is why I’m now writing about it.)
Imagine you have a console app you are developing in VS2003. This app has a file reference to a library, say reflib.dll, with a version of 188.8.131.52 and a file version of 184.108.40.206 with a Copy Local property set to True. You develop away earning your substantial hourly rate, build the app, test locally, and everything works great. Time to move to a test environment, so you package it up and deploy the contents of the local build directory to the test server and testing begins.
Bam! It blows up saying it can’t find a reference. You dig a little deeper and find the missing reference is a dependency of reflib.dll, say reflib2.dll, with a version of 220.127.116.11 and a file version of 18.104.22.168. You look all over the test server and it’s no where to be found. You say, “Hey, I copied the working version from my local build directory so it must be there and I missed it during the deployment.” So you look in your local build directory and it’s not there. What the hell? How did the local copy work if reflib2.dll isn’t there?
I purposefully did not mention that earlier you were working on another project that required reflib2.dll to be GAC’d. That older project was developed, tested, and deployed…but to another server different from your test server for the current app you’re working on.
Anyone know the cause yet?
Yep…damn GAC. When VS2003 does a build where there are references which have dependencies on other assemblies not directly referenced, it does not copy them locally if that assembly is in the GAC. Even if Copy Local is set to True for the reference.
Digging a little deeper, the issue isn’t quite that cut and dry. Even though the CLR does not care about File Version values, apparently VS2003 does. Meaning if the version of reflib2.dll in the GAC is 22.214.171.124 with a file version of 126.96.36.199, VS2003 does not copy the file locally. If you were to keep that version in the GAC but update the referenced version to have a version of 188.8.131.52 with a file version of 184.108.40.206, VS2003 WILL copy the file locally.
1) Remove the version from the GAC when building an app that needs a local copy.
2) Add a post-build xcopy event to the project to manually copy the dependency to the build directory
3) Use a continuous build tool (CruiseControl is what we’re using right now) to perform the build on another server that does not build the app with the GAC requirement
So far I’m stuck at 2. 3 sounds good as long as the tool can manage it. I really don’t know, but will look into it a bit more later.
But wait, there’s more! Ok, you’ve got all that figured out and added a post-build. Now you decide to create a Deployment package (MSI) that includes this application. So you create the project and add the project output to the package. Guess what? Same issue. Although a bit worse, since the best the deployment package can do is pull the build output. A post-build xcopy to include a file in a build directory is not part of the build output, so the MSI does not contain those files. Which means the dependencies do not get deployed with the application. So now we’re back to the same solution of trying to manually include the dependent files in the deployment package through a direct file add. Not very scalable.
But wait, there’s more, Part II!! If you’re working with a web project you can’t assign post-build events to the project. What I’ve thought of so far is creating a dummy project for your web project to reference, and in that project perform your post-build event. Risky and a hack, yes. Other than that, manually copy the files. That’s what I’m sticking with for now…I’ve spent too much time on this as it is.