I create my first TFS (2013 Express) project and added my solution (MVC5) to that project.
I then checked everything in and deleted it and restored from TFS to ensure that I have a working copy.
It was at this point I realized that I have a "DLL Reference" folder that sits outside of my solution.
What is the proper way for storing 3rd party dll referenced like this in TFS so that I can ensure I have a working solution?
EDIT:
This is not dll's from Nuget. These are 3rd party dll's that I am referencing from a folder.
Create a folder in TFS at solution level, call it dependencies, binaries or give any name you prefer. Add 3rd party files to this folder. Remove and add references to your project from this folder.
The easy-though-not-so-clean way is to create a dummy project, with no source files and a single folder (you could use the assemblies folder you already have) containing your dependencies. You can then add the dummy project to your solution and it will be synchronized by TFS.
There is an alternative solution, without including a dummy project.
From within Visual Studio, you can use Source Control Explorer to add files to TFS even if they are not in a project of your solution.
You can also do this from Windows Explorer. As long as you are in a folder that is part of a configured Workspace, you should be able see a "Team Foundation Server" drop-down menu when you right-click the folder.
The downside to this is that when someone needs to download your solution files to a new machine, they will have to manually download that folder too (via Source Control Explorer or Windows Explorer).
I know I'm a bit late to the party, but for anyone having a similar problem, you can create a folder in your project called "ExternalDLLs" and add the DLLs you need in there. Add references to these DLLs in your Project. Then include this folder in your Source Control and Push it up.
By default, Source Controls, ignore files with certain extensions (e.g. dll). Ensure that you add this folder to the Source Control, you can usually do it from your IDE or there may be a .gitignore file (or similar)
If you are trying to Push the bin folder with the DLLs up to your Source Control, the bin folder contents become Read-Only. That is why, this separate folder needs to be created.
I always recommend against committing binaries to source control. One way you can maintain these dependencies is to create your own nuget package, and host it internally on your own nuget server.
Related
I have a WPF app that works with local SQLite and Entity Framework Core. I want to distribute my app using ClickOnce.
Everything works fine when I run it using Visual Studio 2017. But app had a crash on a start when I used ClickOnce. The crash was so early so I couldn't even log the exception. After some time I found that in publish folder some dlls were missed. For example System.Runtime. All references are NuGet packages. Then I found that despite of I have a reference to the dlls in my project ClickOnce application files list doesn't contains it.
The only solution I have found for now is to add missed dlls as files in root of my project and set build action to Content. In ClickOnce application file dialog I set publish status to Include.
It works now but it looks like not the best way to do it. The question is why they are missed in the first place. More likely I missed something or I am not understand the root of the problem.
UPD:
You can find an example code here.
It works from Visual Studio but crashes on a start when you try to install it as ClickOnce application.
UPD: The problem was fixed in Visual Studio Professional version 15.6.1
There are two ways solving solve this.
At first, you have to go Properties → Publish → Application Files, and at this place, make your DLL files include in your project
But if it does not work, go to References and make the DLL file CopyLocal = False. You add a DLL file like Existing Item in your project and make them Copy Always.
It will work correctly.
But for your sample I watch this and I solved it. Look at this image:
You have four DLL files. You need do this for them:
System.Diagnostics.Tracing.dll
System.Reflection.dll
System.Runtime.dll
System.Runtime.Extensions.dll
At first go to your reference and make them Copy Local False:
Then go to the path of each DLL file and add them like Existing Item, and then make all of them Copy To Output Directory CopyAlways
Then Publish it and run it like in this picture. I run it from publish file and it works.
Even if you set the dll to copy local, the dll will not get copied over unless you actually use the dll in your code. You might try adding System.Runtime in your code somewhere like this maybe?
var dummytest = System.Runtime.GCSettings.IsServerGC;
Based on Issue 9 on https://blogs.msdn.microsoft.com/bclteam/p/asynctargetingpackkb/ I was able to do the following:
Symptom
ClickOnce applications targeting .NET Framework 4.0 that reference the Microsoft.Bcl or Microsoft.Bcl.Async packages may experience a TypeLoadException or other errors after being installed.
Resolution
This occurs because ClickOnce fails to deploy certain required assemblies. As a workaround, do the following:
Right-click on the project and choose Add Existing Item
Browse to the folder where the System.Runtime.dll lives
In the File name text box paste in the path of the file
Click the down-arrow next to the Add button and choose Add as Link
In Solution Explorer, holding CTRL select System.Runtime.dll
Right-click the selection, choose Properties and change Copy to Output Directory to Copy always
Republish
I am setting up an installer project for a C# solution and I encounter a dependency problem:
In my solution, I have 4 independent project outputs – one windows service and three executables, who all share between them some references.
I need the installer to install all four of them in order for the solution to work.
I've set up an installation folder for each project output under "Application folder" in the "File system on target machine" dialog, added the project output of the windows service successfully in its folder. But when I continue to try and add the executables' project outputs in their folders the assemblies already carried into the windows service folder are not carried into the executable folder, and following the installation the executables won't run as they are missing dependencies.
I can manually add the missing assemblies to the executables' folders, but it seems that this is not how it should be done and there's something I'm missing.
Any ideas?
Well you should create a new project in the solution, and set the "installer" to be the output of your main application (or main applications) it should solve the dependencies itself.
I was having what I think is the problem that was originally described. I have a Winform app and a console application as two separate projects, but a single setup project handles both.
Both the Winform app and the console app use the same two external assemblies: one not part of the solution (reference to a file in a folder), and the other from a C# class project (reference to the project).
What I have found is that the installer assumes that the project output is all combined into a single folder on the installation machine. Therefore, all of the common assemblies will also co-reside with the executables that need them. So if you add the project output from the first executable into the folder, that is why you see all its dependencies appear, and then when the second project output is added, only the assemblies not already added will appear.
It doesn't matter if you create subfolders under the Application folder, Visual Studio appears to treat the Application Folder as a whole unit... as far as Project Output (exe, dll and res) are concerned.
There are two ways to solve this. The first is to create a separate installation project for each executable. In a large project, this could be a lot of setup projects.
If you want to keep everything in a single installation, a better option is to use the GAC for the shared assemblies, which is described in another Stack Overflow article here: Use Visual Studio Setup Project to automatically register and GAC a COM Interop DLL
MSI can get the job done. Right-click "File System on Target Machine",
Add, GAC. Right-click that added folder, Add, Project Output. That
ensures the assembly is gac-ed.
The GAC is the better solution in my mind, because your assemblies are managed by the .NET layer if you later make changes and enhancements to them. One of the benefits of .NET is to eliminate the old "DLL hell" issues that were in Win 98 and previous versions of Windows. I highly recommend using it for your common code.
I finished a project.I am trying create a setup .
My Problem is that :after I create setup project dll files that I used in project added to same folder with my .exe file like
ApplicationFolder(Folder)
Devexpress.Data.dll
Devexpress.Util..dll
.
.
project.exe
but I want to get it different folder.
like
ApplicationFolder(Folder)
MYDLLFILES(Folder)
project.exe(exe file)
how can I make this? Thanks a lot
This is not only a problem of setup. unless you are already handling this in the app.config and/or with appdomain.assemblyresolve event your application will not work at all on the user's machines once those required references will not be available in the same folder if the .exe file.
Surely you could isolate every single file and tell the setup project where to put it but your program has to be modifief to then look for those files in those other locations.
I accidentally faced this problem today, I want to add some separate dll files into the setup package (I have to do this because I can't add reference of these dll files into my C# program , these dll files are of 3rd-party software).
I did as following:
Right click on Setup Project > Add > Assembly and then browse to dll which I need, then press OK button.
These dll files will be included into Setup project, and will be packaged into setup file also.
Hth.
The problem is that Visual Studio setup projects will automatically include referenced DLLs for you so you won't be able to customize their location with these setup projects.
See also the following articles by DevExpress:
How to deploy WinForms applications on client machines
How to distribute applications which use Developer Express .NET Windows Forms controls
The second article explains how to register DLLs copied to a different location.
By the way we're also also deploying a big app using these VS setup projects and our base installation folder is full of DevExpress and other DLLs. I agree that it looks totally ugly and I'd also prefer a clean structure with a lib subfolder, but nobody cares about that. Customers don't start our application from the installation folder, they use the shortcuts.
My problem is that DLLs needed by my ClickOnce app are cluttering my project folder and I would like to move them to a bin folder but don't know a simple way to do so and still get the files to distribute.
To explain:
I'm distributing a C# app with ClickOnce. It has the following components:
One C# application
One CLR DLL
Umpteen C++ DLLs
All of these build to a tidy little bin folder.
Now the CLR DLL is referenced from the C# project, so it copies and deploys fine.
But I also want to distribute the C++ DLLs as part of the ClickOnce project, so I've done the thing that people say to do, which is add them to the C# project (drag ... drop), and in Properties, set Build Action to Content and Copy to Output Directory to Copy if Newer.
ClickOnce seems to deploy these files quite nicely.
The problem, though, is that now I have a bunch of binaries dumped into my C# project folder (and appearing in the project root in the IDE), which mixes executable files with source files in a way that is extremely obnoxious.
Can anyone clue me in to a simple way to keep all my DLLs in the output folder where they belong, and also have them distributed by ClickOnce?
Move you C++ DLLs somewhere sensible then when you add them to the project choose to add them as a Link instead of the standard Add which copies the files to the project folder.
To do this follow these steps:
Right click the project file and choose add existing file.
Navigate to the location of the file(s).
Click the down arrow next to the Add button and select Add as Link
We are using TFS and VS 2010.
I have been working on a project that is using TFS as source control.
I have quite a few dlls that I have downloaded (such as log4net) and referenced in my project.
When a new programmer connected to TFS and got my project out of source control, it failed to build as it said it was missing all these referenced dlls.
What did I do wrong here? How can I include those referenced DLLs in source control.
Do I need to add all these dlls to my project before referencing them? when I referenced them, I just browsed to where they were on my file system.
I've found the best practice for 3rd party DLLs is to create a "Library" folder in your sln/proj file structure and copy all the necessary DLLs into this local folder for reference. You'll also want to make sure these DLLs are checked into source control. This way, everyone who works on the project gets the exact same versions of all DLLs, and the reference paths are exactly the same.
Referencing 3rd party libs in a arbitrary download or install location will be problematic, because it will require all developers to maintain the same download structure for all DLLs. Also, if everyone references DLLs outside of the project structure, it's harder to guarantee that everyone's on the same version.
The other option would be to have everyone install the DLLs into the GAC, but that can be a real pain too, especially with version management and deployment.
I created a "ThirdPartyDLL" folder in my project folder in which I copied all the extra DLLs into it. I then went into source explorer and added those DLLs into the team foundation server so I could be sure I'm using the correct versions of the DLLS for specific versions of my application (and so everyone else is on the exact same page as I am).
View - other windows - Source coontrol explorer
Right click project folder - add items to folder
You won't be able to select a specific folder with DLLs in it, but instead you can select the individual DLL files within the folder. You will then see the "ThirdPartyDLL" folder appear in that window.
Once this is done, those dlls are in the team foundation source control. Whenever a dev checks in, they will get the most current version of the DLLs.
Don't forget to remove the old references in your app and change them to your thirdpartydll folder.
I used to copy the DLLs into the bin folder but the issue I ran into was when the DLLs got upgraded. Initially when my project was small it wasn't a big deal. Now that I have multiple DLLs and applications that I created it became very difficult to maintain consistent versions of DLLs outside my project. My best example is the licensing dll I purchased. When this got upgraded all applications and libraries needed to be on the same version. If I forgot one then I had weird issues or the application just stopped working. Now that I have everything in one folder, I make the change once and everything is upgraded.
Hope this helps.
Andy's suggestion is a good one and I've used that in the past. At my current job, we have a "reference" folder on a network share for all of us to build from. We have a very fast network here, though and all developers are in a single office. This solution won't work as well if you have a lot of remote developers or a slow network.
I've tried various methods for dealing with this and have settled on dropping required dll's in the bin folder and making sure they are included in the project for source control. I've heard people say this might not be a good idea but nobody has provided good reasoning for it and it's worked well for me.
My second choice would be to carve out some space on a network share and organize the various 3rd party dll's there. You can put your files in folders with verion numbers to keep things straight and everyone should have access to everything they need, so long as everyone uses the normal network paths as a reference.
Adding a seperate folder within the project is also workable but seems messy, since you end up with extra files that you don't want included in your release.