I have Visual Studio 2019.
I know we can build one project with multiple configurations, and have a dll per configuration, for example we can have one dll for the Debug configuration of our project and we can have one dll for the Release configuration of our project.
But my question is how to have multiple dlls for one project based on DefineConstants, for example one dll when we <DefineConstants>ML_HOOSHANG</DefineConstants> and have another dll for this project without define this constant?
Another question is how to package this project with hold all of these dlls per definition of our define constants?
Another question is, can I force Visual Studio (msbuild) to generate all dlls per build request?
Is UsingTask useful for this purpose? or not?
Is there anyway to change DefineConstants per UsingTask?
How to create multiple assets (dll) for one project with msbuild
depend on Constants value?
You may get some hint from this issue. Batch build in VS2019 is something that can help for your issue.
Possible direction:
Create one new project named TestBatchBuild. Right click Solution=>Configuration Manager and create new project configuration NewDebug and NewRelease.(Copy settings from Debug and Release)
Now right click solution=>batch build we can see:
Then let's edit the project file(xx.csproj) and we can find four PropertyGroup. Add <DefineConstants>ML_HOOSHANG</DefineConstants> to NewDebug and NewRelease PropertyGroup and Save ALL.
Now building with NewDebug equals to build with Debug+DefineConstants. And building with NewRelease equals to build with Release+DefineConstants. Now let's go batch build page, we can build four assemblies at one time. (Debug+nodef..., Debug+def...,Release+nodef...,Release+def...). Hope all above helps.
Iv'e downloaded a C# interval tree collection class class from here http://intervaltree.codeplex.com/SourceControl/list/changesets -> Right hand side -> Download.
However I can't open the whole project on my Microsoft Visual C# 2010 Express (that also runs C# XNA) because
Solution folders are not supported in this version of the application
Also I just want the class to use separately in my own seprate project.
I tried to copy the three important seeming files Interval.cs, IntervalNode.cs and IntervalTree.cs into my project but this generated the compile error
There are no importers which handle this file type
I've also tried to copy and paste the contents of the three files into my project, encapsulating them into there own namespace as well as there was a lot of code. I had to rearange some of the usings a little but have run into the problem that possibly it wants PowerCollections .dll and .pcb files as using Wintellect.PowerCollections; causes
The type or namespace name 'Wintellect' could not be found (are you missing a using directive or an assembly reference?)
I'm not sure how to continue or if I'm doing the right thing at all in how to get this class to work.
Add the library to your solution
Copy the IntervalTreeLib directory into your solution directory. Then, right-click your solution, and add existing project. Point it at IntervalTreeLib.csproj in IntervalTreeLib, and click Open. That should add the IntervalTreeLib project to your solution.
Add a reference to the library in your project
Then, in your project, add a reference to the IntervalTreeLib proejct:
- Right click the References folder, and Add Reference. Click the Projects tab, and select IntervalTreeLib.
Use the classes in your code
To use classes from the library in your source then, you need to either add:
using IntervalTreeLib;
void Foo() {
IntervalTree<int, int> tree = new ...
}
Or, refer to them by their full name:
IntervalTreeLib.IntervalTree<int, int> tree = new ...
Open the IntervalTreeLib.csproj file if you want to be able to open the project in it's entirety (or in your current solution add an existing project (you can right-click on the solution) and select the IntervalTreeLib.csproj). If you are trying to grab just the code file in your project, ensure you also grab the PowerCollections.dll file (I see it is in the same folder as the code files) or your code will not compile (as you have discovered). You'll need to add a reference to it and include the needed using statement at the top of the code files making use of this library (or use fully qualified name with the namespace).
using IntervalTreeLib;
or
var myObj = new IntervalTreeLib.[WhateverClass](...);
Also, make sure you read the license.txt file. You may need to include it if you are using the code. Give credit where it is due.
UPDATE:
If the test project is causing you problems, just open the library project. Ideally you could just open that and compile it, adding the output DLL files that are generated directly into your solution. This is ideal unless you are planning on changing the library source code itself.
Add the library to the references of the project you want to use it.
Since discussing that you are able to build Intervallib.dll, we will discuss about how you should the dll in your project.
Now in your proj, right click on the references part and add the dll intervallib.dll to your references. In your game.cs file, have the reference to the namespace as -- using IntervalTreeLib;
then you should actually copy the dll powercollections.dll to the bin directory of proj directory also.
you should copy this dll because there is an indirect link to the dll as it is used in IntervalTreeLib.dll
following these steps, I was able to execute this project.
I have a solution in visual studio where one project (.csproj) is set to create an exe.
I would need to create a duplicate copy of this project so that I can name it something different and change the icon for it. (All of the rest of the projects can stay the same)
I am using conditional compilation symbols for that project, but I don't want to create a whole separate solution configuration because that requires expensive rebuilding of the entire solution.
In Visual Studio under Build -> Configuration Manager, you can create a new configuration for your project and clone it from your release build, then in your project properties you can customize it.
For the icon, you'll want to refer to Set a different ApplicationIcon for each build configuration
Create a copy of the project on disk (outside Visual Studio) and add the copied project to the solution. Then you can modify output assembly name, icon. etc..
However better practice would be to perform the necessary operations as postbuild step (e.g. batch/powershell script) as you will have to keep the projects synchronized (added/renamed/removed files, references...)
Copy it somewhere else and change the assembly name and namespace may be on the project property window( right click and property)
I dont know what your trying to accompish but possible solutions:
add post build event that will copy exe / (exe ad dll-s) to another directory
if you use TFS, edit your Build so it will create copys
Cheerz,
I have a visual studio solution.
I have many projects in the solution.
There is one main project which acts as the start up and uses other projects.
There is one project say "ProjectX". Its reference is added to main project.
The ProjectX references another .NET dll (say abc.dll) that isn't part of the solution.
Now this abc.dll should be copied to bin/debug folder of main project, but it isn't getting copied there. Why is it not getting copied, any known reasons ?
I found that if ProjectX referenced the abc.dll but didn't directly use any of the types DEFINED in abc.dll, then abc.dll would NOT be copied to the main output folder. (It would be copied to the ProjectX output folder, to make it extra-confusing.)
So, if you're not explicitly using any of the types from abc.dll anywhere in ProjectX, then put a dummy declaration somewhere in one of the files in ProjectX.
AbcDll.AnyClass dummy006; // this will be enough to cause the DLL to be copied
You don't need to do this for every class -- just once will be enough to make the DLL copy and everything work as expected.
Addendum: Note that this may work for debug mode, but NOT for release. See #nvirth's answer for details.
Just a sidenote to Overlord Zurg's answer.
I've added the dummy reference this way, and it worked in Debug mode:
public class DummyClass
{
private static void Dummy()
{
var dummy = typeof(AbcDll.AnyClass);
}
}
But in Release mode, the dependent dll still did not get copied.
This worked however:
public class DummyClass
{
private static void Dummy()
{
Action<Type> noop = _ => {};
var dummy = typeof(AbcDll.AnyClass);
noop(dummy);
}
}
This infomation actually costed me hours to figure out, so I thought I share it.
Yes, you'll need to set Copy Local to true. However, I'm pretty sure you'll also need to reference that assembly from the main project and set Copy Local to true as well - it doesn't just get copied from a dependent assembly.
You can get to the Copy Local property by clicking on the assembly under References and pressing F4.
It looks slick when you make it an assembly attribute
[AttributeUsage(AttributeTargets.Assembly)]
public class ForceAssemblyReference: Attribute
{
public ForceAssemblyReference(Type forcedType)
{
//not sure if these two lines are required since
//the type is passed to constructor as parameter,
//thus effectively being used
Action<Type> noop = _ => { };
noop(forcedType);
}
}
The usage will be:
[assembly: ForceAssemblyReference(typeof(AbcDll.AnyClass))]
Ran into this same issue. Background info: before building, I had added a new Project X to the solution. Project Y depended on Project X and Project A, B, C depended on Project Y.
Build errors were that Project A, B, C, Y, and X dlls could not be found.
Root cause was that newly created Project X targeted .NET 4.5 while the rest of the solution projects targeted .NET 4.5.1. Project X didn't build causing the rest of the Projects to not build either.
Make sure any newly added Projects target the same .NET version as the rest of the solution.
Not sure if this helps but for me, many times I reference a DLL (which automatically adds it to the bin folder of course). However that DLL might need additional DLLs (depending on what functions I'm using). I do NOT want to reference those in my Project because they just simply need to end up in the same folder as the DLL I am actually using.
I accomplish this in Visual Studio by "Adding an existing file". You should be able to add it anywhere except the Add_data folder. personally I just add it to the root.
Then change the properties of that file to ...
Build Action = None (having this set to something like Content actually copies the "root" version to the root, plus a copy in the Bin).
Copy to output folder = Copy if Newer (Basically puts it in the BIN folder only if it is missing, but doesn't do it after that)
When I publish.. my added DLL's only exists in the BIN folder and nowhere else in the Publish location (which is what I want).
You could also check to make sure the DLLs you're looking for aren't included in the GAC. I believe Visual Studio is being smart about not copying those files if it already exists in the GAC on the build machine.
I recently ran in this situation where I'd been testing an SSIS package that needed assemblies to exist in the GAC. I'd since forgotten that and was wondering why those DLLs weren't coming out during a build.
To check what's in the GAC (from a Visual Studio Developer Command Prompt):
gacutil -l
Or output to a file to make it easier to read:
gacutil -l > output.txt
notepad.exe output.txt
To remove an assembly:
gacutil -u MyProjectAssemblyName
I should also note, that once I removed the files from the GAC they were correctly output in the \bin directory after a build (Even for assemblies that were not directly referenced in the root project). This was on Visual Studio 2013 Update 5.
If you right Click the referenced assembly, you will see a property called Copy Local. If Copy Local is set to true, then the assembly should be included in the bin. However, there seams to be a problem with Visual studio, that sometimes it does not include the referenced dll in the bin folder... this is the workaround that worked for me:
In my case, it was the stupidest thing, caused by a default behavior of TFS/VS that I disagree with.
Since adding the dll as a reference to the main project did not work, I decided to add it as an "Existing Item", with Copy Local = Always. Even then the file was not there.
Turns out that, even though the file is present on the VS Solution and everything compiled both locally and on the server, VS/TFS did not add actually add the file to source control. It was not included on the "Pending Changes" at all. I had to manually go to the Source Control Explorer and explicitly click on the "Add items to folder" icon.
Stupid because I've been developing for 15 years in VS. I've run into this before, I just did not remember and somehow I missed it because everything still compiled because of the file being a regular reference, but the file that was added as Existing Item was not being copied because it did not exist on the source control server.
I hope this saves someone some time, since I lost 2 days of my life to this.
Issue:
Encountered with a similar issue for a NuGet package DLL (Newtonsoft.json.dll) where the build output doesn't include the referenced DLL. But the compilation goes thru fine.
Fix:
Go through your projects in a text editor and look for references with "Private" tags in them. Like True or False. “Private” is a synonym for “Copy Local.” Somewhere in the actions, MSBuild is taking to locate dependencies, it’s finding your dependency somewhere else and deciding not to copy it.
So, go through each .csproj/.vbproj file and remove the tags manually. Rebuild, and everything works in both Visual Studio and MSBuild. Once you’ve got that working, you can go back in and update the to where you think they need to be.
Reference:
https://www.paraesthesia.com/archive/2008/02/13/what-to-do-if-copy-local-works-in-vs-but.aspx/
Make sure that the dependent DLL used by you does not have target .NET Framework higher than the target .NET framework of your project's Application.
You can check this by selecting your project, then press ALT+ENTER, then select Application from left side and then select Target Framework of your project.
Suppose,
dependent DLL Target Framework = 4.0 and
Application DLL Target Framework = 3.5 then change this to 4.0
Thank you!
This is a slight tweak on nvirth's example
internal class DummyClass
{
private static void Dummy()
{
Noop(typeof(AbcDll.AnyClass));
}
private static void Noop(Type _) { }
}
I would do add it to Postbuild events to copy necessary libraries to the output directories. Something like XCopy pathtolibraries targetdirectory
You can find them on project properties -> Build Events.
TLDR; Visual Studio 2019 may simply need a restart.
I encountered this situation using projects based on Microsoft.NET.Sdk project.
<Project Sdk="Microsoft.NET.Sdk">
Specifically:
Project1: targets .netstandard2.1
references Microsoft.Extensions.Logging.Console via Nuget
Project2: targets .netstandard2.1
references Project1 via a Project reference
Project2Tests: targets .netcoreapp3.1
references Project2 via a Project reference
At test execution, I received the error messaging indicating that Microsoft.Extensions.Logging.Console could not be found, and it was indeed not in the output directory.
I decided to work around the issue by adding Microsoft.Extensions.Logging.Console to Project2, only to discover that Visual Studio's Nuget Manager did not list Microsoft.Extensions.Logging.Console as installed in Project1, despite it's presence in the Project1.csproj file.
A simple shut down and restart of Visual Studio resolved the problem without the need to add an extra reference. Perhaps this will save someone 45 minutes of lost productivity :-)
You may set both the main project and ProjectX's build output path to the same folder, then you can get all the dlls you need in that folder.
NO NEED FOR DUMMY IN CODE
Just :
add a Reference to the Executeable Project
or/and ensure that the reference in the executeable project has "Copy Local" set to TRUE (which was my "fault") is seems that this "overwrote" the setting in the base referenced library-project...
Other than the common ones above, I had a multi-project solution to publish. Apparently some files target different frameworks.
So my solution: Properties > Specific Version (False)
Add the DLL as an existing item to one of the projects and it should be sorted
VS2019 V16.6.3
For me the problem was somehow the main .proj file ended up with an entry like this for the project whose DLL wasn't getting copied to the parent project bin folder:
<ProjectReference Include="Project B.csproj">
<Project>{blah blah}</Project>
<Name>Project B</Name>
<Private>True</Private>
</ProjectReference>
I manually deleted the line <Private>True</Private> and the DLL was then copied to the main project bin folder on every build of the main project.
If you go to the reference of the problem project in the references folder of the main project, click it and view properties there is a "Copy Local" setting. The private tag equates to this setting, but for me for some reason changing copy local had no effect on the private tag in the .proj file.
Annoyingly I didn't change the copy local value for the reference, no idea how it got set that way and another day wasted tracking down a stupid problem with VS.
Thanks to all the other answers that helped zone me in on the cause.
HTH
I had a similar issue in which a DLL I had included in the project as content and 'Copy always' set, wasn't being copied to the bin folder. I solved this by adding a dependentAssembly reference to the DLL in the app.config.
I'm trying to create post build events to copy the final .js and .debug.js files for my script# projects into the proper directories. I can't use the regular output folder, since I have more than one project that references another project, and that always results in a build error (Unable to copy referenced script because it is being used by another process).
The problem is that the C# compiler appears to run the post build events BEFORE it writes the actual .js files, so they don't exist when the post build event happens.
Is there any other solution to make this work?
You can set up a DeploymentPath property in your csproj and the generated scripts will be copied there.
All of the logic is in here: https://github.com/nikhilk/scriptsharp/blob/cc/src/Core/Build/Tasks/ScriptCompilerTask.cs ... so another option is to customize the build task to exactly your requirements.
The latest work if you check out the github repo, also has the script# part of the build process done during the build step of an msbuild project, so that should free up the post-build step for you to do what you'd like with the generated scripts. See https://github.com/nikhilk/scriptsharp/blob/cc/src/Core/Build/ScriptSharp.targets. Again, its just msbuild stuff, so you could potentially customize the .targets file to your liking as well if it doesn't fit your needs.
I got around this by adding the "copy" command as a pre build step on the projects that were using the script# project output, then adding a dependency so that the script# project would be built first.