In our environment, we have two in-house frameworks and a separate website. During development, the references to the in-house frameworks tend to be set tp project references. However, once we move to release, the in-house frameworks are installed into the GAC as they are used for multiple instances of the website on each server. All of the ProjectReferences are changed, by hand, to References and the website assemblies and website are re-compiled and deployed.
I am attempting to automate this process. What is the best way to handle these issues? I have started to learn MsBuild in the attempt to accomplish this, but am totally confused. Any pointers and/or suggestions on how to proceed?
As far as I am aware there shouldn't be any need to change from using project references to file references simply because the assembly is registered in the GAC - as long as the referenced project is strongly typed at the point that it is built, the reference should still be valid.
Clarification:
There is no fundamental difference between a GAC reference and a file reference - if you have a reference to a strongly named assembly, and that assembly is placed in the GAC then the end application will load that assembly from the GAC.
See this link for more information on how the runtime locates referenced assemblies:
http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.71).aspx
FYI - I believe it is recommended that you don't reference assemblies which are in physically in the GAC, and that you instead reference the strongly named assembly before it is placed in the GAC (not to be confused with whether or not the assembly should be installed to the GAC on the end-user machine)
If you leave the project references in, MSBUILD will copy all the project references as DLLs into the target website's bin directory, even though you've installed these DLLs into the GAC, which I assume is why you want to change this at the release level--so that space can be saved.
I also assume that you are intending to do this at the Release Branch only, and not at the development branch of your source control. Because if you are doing this at all branches of source control, then doing by hand is actually the best and fastest way of doing this for a one-time change.
To do this in MSBUILD, you will need to create a custom task that can modify the project file. The project file is an XML file, so you could use XPath as your custom task in MSBUILD. In the project file, you will find tags for "" to your referenced projects. You will need to change those to "" tags instead. Use existing examples of the tag in your project to see how it should look
Sorry I don't have sample code for this--doing it this way will be a bit of an undertaking, as there will be a number of things to take into consideration, and it might end up not being feasible.
Related
I am writing a commercial application in VB.Net using VS2010. My application needs to access a MySQL database. So I have a reference to MySQL.Data.dll in the "References" section of my Project. For licensing reasons, I want to make sure that this dll file is not embedded in my application. From what I read, if I set the "copy local" property to False, then the file is not copied and I need to specifically copy it to my bin directory. So I set it to False and built my project. When I run it, I can still connect to the MySQL database even though the dll is not in the bin directory. To me this indicates that it is being compiled with the build. However, the reference points to a location on my hard drive where the original MySQL.data.dll resides. Could it still find it there when the program is run?
How can I make sure it is not getting compiled? Thanks.
By the way, it is not in the GAC (I checked using gacutil.exe)
If you're referring to having the actual assembly embedded into yours, then no it does not. It can be done, but it does not happen out of the box.
The application looks at many places for your references when it needs to load it.
GAC
Next to the application (maybe also the consuming assembly)
x64 and x86 folders next to the application (maybe also the consuming assembly)
Any paths specified in the app.config/web.config for the referenced assembly.
Keep in mind that just because your application fired up, it doesn't mean it found all of the references. It more than likely hasn't loaded all of them yet as it will only do it once it is needed.
This is driving me crazy. I have developed a .NET COM DLL that is used by a VB6 DLL wrapper in order to update and replace some legacy functions in an application.
I am now trying to remove the requirement to use regasm on client machines so have worked out how to do that on a test DLL which all works fine.
I branched the DLL just in case and added an app.manifest file. Everything else worked out fine and I got it all working. The manifest is embedded and Visual Studio 2012 generates a mydll.dll.manifest file in the release folder.
Then I went back to the original trunk and added an app.manifest file (no point in merging as there were no code changes). I copied the contents of the branch into the app.manifest file and built the release version. The manifest is embedded in the DLL but no mydll.dll.manifest file is generated.
I know that it's not strictly necessary to have the mydll.dll.manifest file but I'd like things to be consistent (and for some reason the test process doesn't produce the same results with the trunk version) so how can I force it to be created?
This is a VB.NET DLL project so it doesn't have (or I can't find) the 'Generate Manifest' property drop down mentioned in the first answer here. How can I set this? Or is there a way to set it by editing the project file directly?
References:
Original walkthrough article and some corrections.
Overview by Junfeng Zhang in two articles plus a useful tool
You are making a fairly common mistake. A reg-free COM manifest helps an application find a COM server without looking in the registry to locate the DLL. Embedding the manifest in the DLL is like trying to solve the chicken and egg problem, Windows cannot possibly find that manifest if it cannot locate the DLL first.
The manifest needs to be part of the client app. Which is tricky since it is VB6, it doesn't support embedding manifests in its executables.
You could tinker with the mt.exe tool, an SDK utility that supports embedding manifests in an executable. You'd have to run it by hand after building the VB6 binaries. That's unfun and very likely to cause trouble when you forget. It is in general not a joyful tool to use, documentation is meager, incomplete and unhelpful, a chronic problem with manifests.
The fall back is a separate app.exe.manifest file, what Windows will look for next when it cannot find a manifest embedded in the executable. Where "app.exe" must be renamed to the name of the VB6 program. The EXE, not the DLL. This now also gives you a chance to avoid having to register the VB6 DLL, presumably what you really want if you truly want to make your program run reg-free. The disadvantage is that it will not work when you debug your VB6 program, wrong EXE. You'd also need a vb6.exe.manifest, located in the VB6 install directory.
Needless to say perhaps, very hard to get ahead with VB6 here. It just wasn't made to help you do this, they didn't have a time machine in 1998.
I have to admit that I don't know VB at all, but in the case of C++ and C# Visual Studio projects I previously had to resort to calling mt.exe in a post-build step in order to get the DLL manifest I wanted. Maybe that workaround would work in your case as well?
I am trying to make a program that works on every operating system by forcing it to load and use the DLL's in the current directory, not the windows directory, but it don't works. I tried to enable "copy local" and change the refference path, but without any success, the program tries to load the DLL's from the windows directory.
My question is: how can I fix this?
The Search Order for DLL's is documented here on MSDN. It also includes instructions on how you can modify the search order so that the local bin directory is searched first, instead of the GAC.
The directory %windir%\assembly is called the GAC. Assemblies are not copied there, but installed typically using gacutil /i or by installation packages.
GAC is a suitable folder for libraries referenced by lots of other libraries and applications in build versions that are not centrally coordinated. Using GAC allows you to have multiple versions of the same library, all of which might be indirectly required even by a single application, installed side by side on the system. Case in point is the .NET framework itself.
The assemblies that you build are probably not that kind. Application assemblies and libraries that are basically part of a single application should never make it to the GAC or you can get into trouble. There is a variety of possible trouble:
one accidentally or intentionally creates different (incompatible) builds of the same library with the same version number.
assembly in GAC references an assembly not in GAC
one app installs the same assembly into GAC, but another app wants to load it from its local folder (where application binaries reside).
Code in the GAC gets a preference when assemblies are loaded. To remove an assembly from the GAC, use gacutil /u.
I am building a SharePoint project and using TFS2010 for my builds. I have used the TFS community build extensions to successfully implement assembly version incrementing which I am happy with.
However, as my assembly is going into the GAC I need to update my ASPX/ASCX files to reference the assembly with the correct version.
Is there a "proper" or easy way to do this?
The markup in ASPX/ASCX files can have tokenized references so it shouldn't be an issue.
<%# Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
Where you have to careful is with web parts and workflows. In both cases the fully qualified name of the assembly that implements the web part or workflow is stored in the content database.
My suggestion is that you do not update the assembly version number unless you plan on running the new version and the old version side-by-side. In the case where you are making changes that will effect currently deployed assets, you should change the assembly file version instead. You'll still be able to distinguish between assemblies but you won't break assembly references.
See Configuring Versioning of Assemblies in SharePoint Automated Build for more discussion on the subject.
I have added reference to few dlls in my VB.net Project. When I check into Visual source safe and get latest version from another machine, VS.net 2008 throws errors.
I have to add the references again in that new machine. Is there anyway where I can keep the references in spite of files checked in to VSS?
I need to send copy all the files to production server and we don't have VS.net on the production box to add reference and build the application.
Thanks
First, be sure that the project file is checked in properly. Sometimes VS fails to regognize that the project file has changed.
A good practice is to check in all the assemblies that your project references, except the standard .NET libraries.
Another recommendation is to set up a build server, which will detect these kinds of problems early. My personal favourite is TeamCity.
For references that are not in the GAC, and if they are third party things that aren't built elsewhere inhouse, a simple approach is to add the referenced assembly as a solution item (Right click on solution node | Add Existing Item). I usually put solution items in the same folder as the sln and then add the reference to that location.
When you check in the solution solution items will go into source control with it.
Use this for small relatively simple applications. If you have more than a handful of referenced solution items follow #Petter's advice and set up a build server with associated configuration management devoted to third party dependencies etc. etc.