during development of our application we use a branching structure and while we are developing another team is using earlier builds of our software to create content with it.
To facilitate easy swapping between builds and teams I was hoping to use empty Hintpaths in the content projects' csproj files so that they can use our GAC installed assemblies to build against and in the meantime add a reference path to the projects for our use during development and test cycles where we don't want any assemblies installed in the GAC.
However, it seems reference paths are not stored in the csproj file and thus don't get sourcecontrolled. Since there will be extensive branching it would be less than ideal to have to set all reference paths again when a developer pulls another branch from sourcecontrol.
I've been searching for a bit now and can't seem to find ways to do this. Anybody know of a way to force the reference path in and out of sourcecontrol?
We're talking Visual Studio 2008 and TFS 2008 here.
Cheers,
Anton.
Ok, I seem to be a little clearer in the head after a good night's sleep, took the logical step, namely investigate where exactly the information was stored and how. It turned out the information was stored in the .user file for the project in the project's folder and as it turens out this file contains mbsuild xml.
I then did what I wanted as follows:
Create the Reference path as I required it to facilitate both scenarios without any work.
Browse to the Project's .user file
Copy the PropertyGroup containing the ReferencePath
Paste the PropertyGroup in all the necessary Projects' .csproj xml.
Reload and build.
Done.
The references are stored in the *.csproj file. The nodes are ItemGroup/Reference...
Thomas
This is pretty simple--we do this in our shop.
First, in the Workspace (using Windows Explorer, browse to the Solution folder), create a folder. We name it "Referenced Assemblies". In here, drop all your DLLs.
Now, in the Solution, add a new folder to match the one created in Windows Explorer. Into that folder, add all the DLLs you just dropped in.
Finally, in each project, set up your references to use the DLLs that were added to the solution.
Now your project references DLLs that are part of the solution, so that when the build runs, it will grab the DLL from Source Control to generate the build.
Also, I'd recommend not using the GAC at all if you can avoid it. In my experience, reference behavior is strange. It seems references go first to the GAC, then to the DLL in the local folder, meaning that if the DLL is updated, the one in the GAC is used instead of the DLL in the local folder (which is likely the updated one).
Related
I am working on a C# program that utilizes EntityFramework, I've cloned the program from git repo, but now it is having that dreadful Metadata file 'EntityFramework.dll' could not be found error. I have searched and tried countless suggestions for this kind of problem, but none worked. I've already checked that the reference to EntityFramework.dll in the .csproj files are correct and it is definitely there under the packages\EntityFramework.6.2.0\lib\net45\ folder. So I am not sure what else to try.
Ok, I've resolved this problem. Here is what happened. Apparently, when cloning into local directory, one of the folder on the path has a space in its name (like My DSS), and this nuget issue seems to indicate the inability of nuget to find package with space in path. So, once I changed that folder's name to MyDSS, it compiled successfully.
please have a look on the bin folder ,sometimes the dlls do not exist there .
This typically happens when teams check in files that should not be checked in (such as the .suo file) or have "optimized" their builds to exclude rarely changed projects. (unticking projects in the configuration manager.)
Another common cause for missing references is when devs reference a dependency from a /bin folder instead of the packages folder, but it sounds like you've confirmed that isn't the case.
Other questions such as Metadata file '.dll' could not be found list a number of things to check, so your problem will surely be one of these. Try building each project individually, working from projects that have no project dependencies upwards to the main application project(s). Ensure they're running the same .Net versions, check the solution NuGet packages for dependencies with "multiple versions" and consolidate these so that the solution is using a single version of each dependency. (generally good for cleaning up) Also look at .config files for version re-directs that sometimes get zombified in source control.
In Visual Studio, on top, click on Build -> Configuration Manager. Make sure that the build checkbox next to your project is checked. In case it already is, uncheck it and then make it checked again. Clean your Solution and Build it again after this.
Me and my team just started using GitHub for our development.
Our project is written within Visual Studio (C#).
In our project files we have external references of .dll files that are saved in specific folder for each user for example (c:\users\$user\dlls\data.dll).
When one user is commiting it's changes - it's also including the .csproj files who contain the links for those .dlls but when another using is pulling from the tree the .csproj contains links from the other user's .dll file and he have to change manually the references in order for it to work.
We tried solving it by putting the .csproj files into .gtignore - though that back fired once our project development expended and each branch has different files.
During the writing of this post I thought of another solution - removing the .csproj from the .gtignore and moving all the external .dlls into folder with an agreed file path such as (c:\dlls) and that might solve our problem.
My question is this:
Is there another solution for our issue?
I haven't tested my suggested my solution I will give it a try next version - What do you think of it? Is that the way to go?
Thanks ahead for your replies,
H.
Why aren't you "sharing" those external DLLs in a folder in your project? What I do is add a folder named "External" in my solution which contains these DLLs (and PDBs and XMLs etc) and make sure it is also checked in. That way whenever someone adds a DLL, all other developers simply need to get the latest files from Git and it is on their machines.
Of course, only do this for DLLs that aren't available from NuGet.
It looks like you need a dependency manager such as NuGet or an alternative one.
I'm looking for a way to detect problems with assembly references in a large Visual Studio solution:
Binary references to bad locations, like a path not in source control or in the output of another project
Binary references to multiple versions of the same assembly across projects in the solution
Binary references without a path, that may be redirected to the GAC
Binary references that should have been project references
The whole story
I work on a large C# project with almost at 200 projects.
One of the problems that is creeping in over time is that references to assemblies are added but not always to the same version or to the correct location.
For example, a project may get a reference to System.Web.Mvc without a hint path, making it reference what ever version is in the GAC. Visual Studio (and Resharper) will also offer to add a missing reference but may do so by adding a reference to the output folder of another project.
Now the recent Windows Update catastrophy left some team members dead in the water, unable to build the solution. As you can imagine, this bumped up the priority of assembly reference management for us.
To detect some of the most obvious problems I've already setup an msbuild file that can be included in every csproj file and will detect bad references.
However, new project files will need to be edited manually to include that script. So that will inevitably be forgotten.
What I would really like is to check all project files in a solution for 'bad' references during the continuous build, so that all projects will be checked always.
I've been googling for a solution like this for some time and found lots of static analysis and code analysis tools but nothing to analyze project files in a solution.
So, before I go off and roll my own solution, is there a way to do this already?
Update
In order to clean up the code base I've created a bit of ScriptCS code that'll scan all csproj files for referenced to assemblies in Nuget packages and fix them. It's up on GitHub.
You can create a NuGet package where the sole purpose is incorporating a custom .targets file into a project. I recently used this strategy to solve another problem (error messages for missing .snk files).
Testing strong names of NuGet-distributed assemblies
Rackspace.KeyReporting source code
If you create a similar package, it's easy to right click on your solution node and verify that it is installed in all of your C# projects.
If your analysis is more complicated and requires the use of an assembly (custom build tasks) in addition to the .targets file, you can use an approach like I use for the Antlr4 NuGet package, which contains build tasks, resources, and custom .props and .targets files, but no actual assemblies that are referenced by the project it gets installed in.
ANTLR 4 C# Target source code (includes the Antlr4 package source and build scripts)
Instead of adding it to all projects in your solution, why not create some kind of test (unit test, build file, whatever) that can take a project file as input, parse it, and throw an error if OE or more references are incorrect. Much easier than adding (and checking out, committing etc) custom build steps to project files.
Even if you would use a nuget package as proposed earlier, you'd still have to check manually whether all your projects (200 projects? Really?) Reference the package.
I've got a C# project in visual studio that is building a DLL, and another console project which includes the first as a reference. These are both in the same solution.
The trouble is when I add methods to the DLL, then rebuild the console project doesn't seem to pick them up.
For example, in the DLL I have a class Converters. If I add a method
public static void test() {}
it just doesnt' show up in the console app at all. Intellisense doesn't autocomplete it, and if I manually type it in it gives a compiler error.
If I go in and delete the dll files then rebuild that works (or better yet, delete the bin and obj directories) but that seems rather drastic.
I'm sure this is a basic error, but I can't seem to find the solution after some googling.
How are you adding the reference? As a project reference or by browsing to the DLL? If you're using the latter then it will copy it locally to the bin directory of your console app and won't refresh it unless you manually delete it. If you add it as a project reference it will copy it as and when it needs to.
The exact thing happened to me once on a project - it turned out the build command wasn't configured to build these DLLs.
Check Build - Configuration Manager, and make sure the project is checked:
(Image from msdb - Setting the Build Configuration)
close Project visualStudio and
rebuild again your dll (other project visualStudio)
One of the things to note is the Target Framework of the Projects, if you compile your Project A with target framework different then that of Project B and it is referencing the dlls of Project A you may run into this kind of trouble. So, make sure that the target framework for both Projects is same.
Check that you don't have the ddl inside the bin folder of your project. Whilst I was adding the reference by browsing for the dll, I had forgotten that I manually copy pasted a version into that folder. No matter how many times I cleaned and rebuilt, it didn't seem to update.
Deleting that dll and re-referencing fixed the issue.
Change the reference to the dll to the Project, instead of the output.
This is certainly unexpected behavior. It sounds like the reference between the two projects is broken in some way. Two issues come to mind.
Possible problem with the reference. Try deleting the reference in solution explorer and readding the reference and seeing if that fixes things. When you re-add make sure it's a project reference and not a file reference.
It's possible that the time stamps on the files in your project are off. See if they are in the future.
check the folder which contains the reference. does it contain a refresh file with a relative path in it? if so, and if assembly names in the location pointed to by the relative path are common with those in of (project) references which should auto update, then these references no longer auto update! what you end up is a static reference to the assemblies present in the relative path contained in the refresh file.
you may also have to delete the projectreferences key in the sln file and add references afresh
I hate to beat a dead SO question but 8 years after the original question and none of the above solving the issue for me, my problem was in VS2013, but to solve it I simply removed and re-added the reference to the DLL in the project that invokes it.
I hope this helps some people in the newer VS realm having the same issue.
I found out that build time of C# solution with many projects gets much faster if you don't have "copy local" enabled everywhere. I did some tests and it seems that (for our solution at least) we could increase build time by factor 2-3 just by removing "Copy local". This probably means we have to store libraries in some common directory.
Any suggestion/best practices how to acheive this? Note that I would like to keep references to projects, not to DLLs.
We retarget the output directory of projects to be ../../Debug (or ../../Release)
Our libs are placed in these directories as well.
We set the reference paths in each project to be the Debug or Release directory accordingly (this setting is persisted in the user files since it is an absolute rather than relative reference)
We keep project references as project references, All dll references have copy local false and specific version false unless they are system level dlls we know will be in the GAC on all deployed machines.
This works a treat and manual builds in the IDE mimic scripted builds from the command line (using MSBuild)
Test projects not for deployment do not direct their output to the centralized Debug|Release directory, they just use the standard default location (and do use copy local to avoid issues with locking)
The library versions may be changed by the automated build process replacing the dlls in the Debug and Release directories.
I recommend building to ..\..\Build if your application is spread across solutions. (If you only have one solution, you may consider ..\Build.) Visual studio will, by default, pick up reference files in it's output folder. When building without VS using MSBuild, though, you must add the build folder as a reference path as shown in the example below:
<Target Name="BuildApp">
<MSBuild
Projects="#(ProjectReference)"
Targets="Rebuild"
Properties="ReferencePath=..\..\Build;$(LibraryFolder)" >
</MSBuild>
<OnError ExecuteTargets="BuildFailed" />
</Target>
The example also takes me to my second argument. I do not think you should use your build folder as library folder, since this may lead to individual projects erroneously overwriting library assemblies e.g. by using Copy Local. You should have strict control over your library versions, so I suggest you keep this separated. (Developers would need to add this path in VS as a reference path.)
You may also choose to separate ..\..\Build into ..\..\Release and ..\..\Debug as suggested by ShuggyCoUk.
I like the top level Bin Lib folder setup that is common in Unix based systems, by the way moving to this type of system will also make your release engineer's life a lot easier as well. Installer Creation is much simplified by only having to pull everyhting out of one folder. Dll's would then go in bin..