I have 3 projects in my solution and a bunch of 3rd party or company dlls. Each time I rebuild my project or clean solution, a lot of this dll's are deleted, therefore missing. It is pretty annoying to reference this dll files again and again after rebuilding. Can someone explain how to avoid this? Thanks in advance.
The bin folder is just the binary output from a build, so when you clean your solution, all the assemblies in the bin folder get deleted. You should reference the assemblies from some other location. One suggestion is to create a Shared Resources folder within your project, copy your assemblies to that folder, then reference them from that folder. This way they won't get deleted from bin on a clean/rebuild and Visual Studio will copy them there as needed.
Right-click on the References folder in your project and choose Add Reference...
Use the browse functionality to locate the assemblies you want to reference (don't worry about manually copying them to/from your bin folder)
After the reference is added, right-click on the reference in your references list and choose Properties
Make sure the Copy Local property is set to True
This will ensure that assembly is copied to your bin folder on every build.
In my case, .net framework version is the problem. I had to lower its version to 4.5 and then the projects got built properly and able to reference in other projects
As Troy explained in his answer, indeed a reference to a *.dll file, kept outside the bin folder, ensures that the dll file does not get definitively wiped out when cleanning the project.
However, just by adding a reference to the assembly might not be enough. For instance it would not work for some other file types, such as the *.pdb files as well as for the *.resources.dll files (which are typically spread in many sub-folders named after the language codes (2 letters' language code)
To depict this problem with a real life situation, I picked up an assembly for which the source code is either gone, or not compatible anymore, etc. I chose (on purpose...) a 13 years old AjaxControlToolkit composed of many component files. The picture below illustrate its composition. Every time the "Clean" command is applied to the project all these files are deleted, except the one which is the referenced assembly. Moreover having several *.resources.dll file assemblies of the same name, as in the present case, makes it inconvenient, if not possible, to add "references" to each of them from within the same project.
Nevertheless here is a pretty simple workaround:
keep this file hierarchy in a separate folder (as Troy explained in his answer)
just copy them over in the bin folder using a command line entered in the Pre-build event of the project, such as xcopy "$(SolutionDir)AjaxControlToolkit" "$(TargetDir)" /y /i /s /r /q
Hoping that will be useful to someone...
Related
I have a solution with multiple MVC and libraries projects and the build of this solution is very slow.
To improve the build performance, I changed all projects to output in the same folder and changed all project references to copy local = false, this improved the build performance almost in 90%, from 10m to 1m30s.
However, this generated an issue, in run mode my application show errors because have no references assemblies in the output folder.
I'd like to know if exists a way, to make solution copy the references only one time to my output folder.
I tried somethings, like a target to copy the dlls from packages folder to the output folder, but this not work correctly, because in a packages folder can exists dlls from many framework versions.
Any ideia to solve this issue?
One common solution is to have all projects output to the same directory, and have all references set to CopyLocal=False, and then have one extra project (or an existing one, like the main application) targetting the same output directory and which contains all references and has CopyLocal=True. Then that one project effectively takes care of getting all your references where you want them. To get all projects use the same output directory I'd suggest to modify the .csproj files to all import the same file which sets the OutputPath property instead of manually changing it in each project.
Alternatively, since you mention the main problem with a single output directory and CopyLocal set to True is that some files get copied multiple times, you could modify how the copying occurs. Normally, by default, the Copy tasks used will skip files with matching timestamps. This is controlled by the SkipCopyUnchangedFiles flag so you could force it to true and see if that changes anything:
msbuild my.sln /p:SkipCopyUnchangedFiles=True
Or you could even ask it to use hardlinks instead of copying, this should effectively mean no copies are made at all:
msbuild my.sln /p:CreateHardLinksForCopyLocalIfPossible=True
or symbolic links:
msbuild my.sln /p:CreateSymbolicLinksForCopyLocalIfPossible=True
If all else fails and files are still copied more than once it could mean e.g. that one project references A.dll and another one also references A.dll but from a different directory or a different version etc, so it will get copied twice no matter what unless you fix that.
I got a c# solution developed by other developers.
This solution contains 30 projects and there is also git folder.
Every project has its bin/ folder. I have web site and class libraries. All the code has poor quality: eg bin e obj folder are included in git.
I'm refactoring the code and reconfiguring also git. I don't want to include bin/ folder in git, so I have created a dll folder in the root of every project containing libraries in the bin/ folder. In this way also references in visual studio have not any warning.
Is it right? Are there other methods?
Second question: if I have a dll in the bin folder not present in the references, would I link that too? Or can I not consider it?
EDIT:
EG: in a class library (not in umbraco project):
- bin/umbraco.dll
- bin/umbraco.provider.dll
- bin/umbraco.core.dll
- bin/lucene.net.dll
In visual studio is referenced only:
- umbraco.dll
So three ways:
Include bin folder in git and if i need to edit this project i will
understand ho configure it;
Add a dll folder in the root (and in git), copy umbraco.dll in it. So references in
visual studio are ok. But only umbraco.dll will be copied in bin
folder. And the Others? Will i need them?
Add a dll folder in the root (and in git), copy all dll files in it.
So references in visual studio are ok. And i take Others for future
uses.
I choosed 3rd solution.
I don't want to include bin folder in git
Simply make sure you have a .gitignore which declares what you don't want:
bin/
That way, you don't even have to create a dll folder. Or if you do, you can ignore bin/dll/ in that same .gitignore file (note the trailing '/' for ignoring folders in a .gitignore).
For CSharp projects, gitignore.io proposes this .gitignore file.
If I ignore bin folder and you pull, the project will not compile!
git should always ignore (big) binaries: those dependencies, as commented by Iain, should comes from an artifact repository (like Nugget) or other externa referential: external to the git source repository, which is made to track the history of sources (text files), not to store binary dependencies.
But if you must, copy only the dll referenced by your project (umbraco.dll) in a versioned folder, and see if the project compile/works. Then add the missing one.
If you have to version those binary dependencies, it is best to try and version only the minimum amount of dlls.
Our project has a lot of external DLLs, most but not all of which are 3rd party DLLs.
Currently we do not have these DLLs included in our project. They are included in SVN and given a path to our build output directory. So, after building our project the neccessary files are there, because of SVN, but the project itself has no knowledge of them.
My feeling is that we should have a folder under the root of our project named something like Dependancies or ThirdParty with all of the DLLs included there and set their build event to copy to the output directory. They would exist in SVN as well, but in the same structure as the project, not in the build output directory.
The project itself only references one of these DLLs called CommunicationProc.DLL. The CommunicationProc.DLL then references all of the other DLLs. We have numerous DLLs to support different types of radio. So not all DLLs will be used, but any one of them may be used depending on the radio type.
As to whether or not the DLLs should be included in the project we have differing opinions internally, some of the team beleives they should only be in SVN and not part of the project itself.
Of note is that this are not .NET DLLs, most are old C DLLs.
What is the accepted practice? Can someone please provide me with a compelling arguement one way or the other as to whether to include them in the project or just SVN?
Its better to have them in a folder on source control and then copy them over to the debug folder on build event. This way you can manage their versions. If a newer version of some dll comes then you can replace the old one and put some comments with check in. Also if you are working in a team, then instead of copying files from debug folder to each team member, you can let each team member to use the same set of dlls from source control. If you are developing some control and want your customers to use that control then its easier for you to have a set of dependent dlls some where so that you can give those to your customer along with your .Net dlls.
I had the same issue with some un-managed dlls and ended up putting them in a folder so that all the team members have the same version of the dlls. Hope this helps.
I include a project that has no code but contains a folder where all the external assemblies and their dependencies are kepts. For each file set the Build Action to None and Copy to Output as Do Not Copyp. The project then references the binaries from this location. In your other projects, reference this special project. When you build, because the special project is referenced and it references all the needed dependencies, the binaries are copied as needed.
If you do not want a special project, still create the folder in your main project, added the assemblies, set their properties, then reference the assemblies as needed.
This gives you complete control over the versions and output, and more importantly, it is simple.
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).
I've always taught myself and others to think of the bin folder as being transient.
That is you should be able to delete it and next time you rebuild it gets recreated and any references get copied into it without any hassle And not to put your eggs all in one basket. Or in this case don't put all your required dlls directly into the bin folder. Have them elsewhere and just reference them.
I've seen people falling down when they put dlls directly into the bin folder and reference them there. So I try to avoid this and put all my required dlls in a folder called Refs and add references to the dlls in there. At compile time they will get copied into the bin folder anyway.
Am I insane? Is this being too careful? common sense?
What is best practice in this scenario?
Cheers,
-- Lee
UPDATE : Turns out i'm not mad
Cheers guys you've picked up on some points I forgot to mention.
Mainly :
Not checking the bin folder into source control
That's right, you don't want to put referenced dlls in the bin folder. If you are using version control, bin and obj folders should always be completely excluded.
All referenced dlls should be included under version control, preferably in a separate subdirectory under your project's trunk, so that everyone has all necessary sources and references for each clean rebuild. bin folder must easily be recreated from scratch.
That's something that I believe most people will expect when checking out your source.
We also include a _READ_ME.txt file in the root of the project, stating additional info on tools and stuff needed to batch-build the project (nant, perl, etc.), so there may be some specific differences from time to time, but never surprises of this kind.
No this makes complete sense and is a practice I myself implement on personal projects. Anything under the bin folder should be treated as property of the msbuild / Visual Studio environment.
While they both take great care to only delete the outputs they know about, it's possible for the user to not fully understand what is the build output and copy over a build output and consequently have it deleted during a "Clean" style operation. It's also possible for other tools to be more aggressive here in cleaning out DLL's. I myself tend to nuke the bin directory from time to time if I think the build process is looking at stale data.
Additionally having a ref's location gives you a single place to update references for a collection of projects within a solution. For me it's a very natural construct.
I think of the bin folder as being transient, it is a place for the full working compiled application to go.
We place any external Assemblies in a directory called Assemblies. Many others use a directory called lib. This separates idea of something that is needed to compile the application from the compiled application itself.
I have no idea if you're insane, but we followed the same practices at the last place I worked and I've carried them over to my own work. The /bin and /obj folders are outside version control and something I never touch. They basically don't exist as far as I'm concerned during development. All included DLLs sit in another folder and are referenced.