Using MS Visual Studio 2008, I created a C# library (let's call it main.dll) that relies on a second library (helper.dll). In the Debug version of main.dll, I set a reference to the debug version of helper.dll. But when I switch to build the Release version of main.dll, the output folder still includes the debug version of helper.dll. I do not see a way to select different versions of helper.dll for different build types. In C++, I could tell the linker what folder to get its files from, but I don't see a way to do that for C#.
The typical way of doing this is to have all of your projects in a single solution, and use project references between them. Then, when you build in Debug, all components will be built and referenced as debug - and likewise for Release.
Alternatively, you can use a single output folder for all your assemblies, reference each binary from there, and ensure that the build order is correct - so that your helper.dll is built to that folder before main.dll is built. This is more prone to failure, though, and requires a greater amount of manual maintenance.
When you switch from Debug to Release, Visual Studio switches from Debug to Release in the bin folder for the output.
Set the "Copy Always" property to true for main.dll. This will insure that it gets copied to the appropriate output folder, and is always referenced.
If the second library helper.dll is being built at the same time in the same solution, you can use a Project reference instead of referencing the .dll directly. Then, you can set up a solution-level configuration for Release mode, and build both projects in Release mode that way.
Related
I have included some native DLLs that my project depends on into the project and set in their properties Build Action to content and Copy to Directory to Copy if newer.
I am now having the annoying behavior that the DLLs are sometimes not being copied to the output directory, when I build a project. The behavior appears to be, that when I select Build they are not being copied, but they are being copied when I select Rebuild. To make matters worse they are sometimes removed and I am not sure when (I believe before performing a normal Build).
So my question is: What am I doing wrong? I have also found people using the Post-Build event to copy the DLLs, so is my way not the correct way to do it?
Edit:
I forgot to mention that I have two projects (on which the project that I am building depends) with the same Dlls included, since they both depend on EmguCV, which uses the native OpenCV Dlls, which are the ones causing the trouble.
I'm working on a C# project that is nearing release. As part of this, I have started building the project and testing it on another machine. This has revealed some odd problems. My biggest concern, though, is that my project is failing to run. I can do some basic things, but when I try to use my projects primary functionality it crashes. Using Visual Studio, I was able to determine the exception that was causing the crash.
Essentially, I'm getting a FileNotFoundException on the dll that contains most of my project's functional code. I'm not sure if I've made an error in adding the dll to my project, or if there's a problem in one of the files in the dll.
The dll was added as a reference using the Project -> Add Reerences feature of the user interface.
The dll contains three files which contain absolute file paths (these are for #import statements). Example follows.
#import "C:\Users\Me\Documents\Projects\MyProject\Delegates\bin\MyDelegate.tlb" raw_interfaces_only
My hang up is I'm not exactly sure what I'm doing wrong here. I suspect that those import statements are causing problems, but I'm not exactly sure how to fix them if they in fact are the problem. This is my first c#/c++ project so any help would be appreciated.
Adding the dll as a reference DOES NOT include the dll with your project--you are simply telling your project to use the library for your code. The dll will need to be installed on all computers that run your application, for your application to use the dll.
If the dll also uses three files (as you specified), then those files must also be included, and be installed in the expected path.
Presuming you have redistribution rights on the dll you mention, you can include the dll in your project. Be sure to set the "copy" property as "copy always" or "copy if newer" and change the reference to use the copy that ends up in you bin folder. Then you only need to be sure to include that dll and install it in the same folder as your application.
I'm adding my dll file to my reference and set Copy local to true
Everything is OK and after I build application, my dll added to output folder
Now my question is how do Ι change the local path?
For example:
my application path is C:\myproject, I want to put dll into C:\myproject\libs
How can I set dll path to {applicatonpath}\libs NOT {applicationpath} ?
When you compile you project, visual studio will put everything that has been compiled and set to copy locally to the "output folder", which depends on your current compile configuration. If you are compiling in Debug mode then this folder will be:
c:\your_solution_path\your_project_path\bin\Debug
If you use Release mode, it will be:
c:\your_solution_path\your_project_path\bin\Release
However, sometimes we reference a lot of assemblies (DLLs if you will) and those assemblies have dependencies of their own. In order to make everything "point and click" for our convenience, we must tell visual studio how we would like it to act for a particular project build.
So, as TotPeRo said, you should go do project properties and use the functionality of Pre-build and Post-build events. As the name suggests, Pre-Build happens before the actual build, while Post-Build takes place immediately after it. Please refer these links for further information: link1 and link2.
Lets assume the following scenario:
You have one solution.
that solution holds 2 projects (let's call them Project A and Project B). Project A is the actual GUI. Project B is just a helper project, that compiles into a DLL.
Let's say, that project B is doing some heavy matrix calculations, so you also have to include some MatLab libraries. NOTE: only Project B uses these libraries.
Project A references project B so that you can use the calculated information from B and show it in gui in A.
In order to compile this, the compiler is smart enough to determine, that Project B should be compiled first. If everything checks, the project is compiled into ProjectB.dll. Then, the compiler proceeds to compile Project A. It check all the dependencies and finds out, that you have already compiled Project B (which is a dependency for Project A) and that it can continue. Everything is then copied to the output folder (bin/Debug or bin/release) and should be in working order.
However, during runtime, something goes wrong and the application crashes. You find out, that Project B does not have the appropriate library to work with (namely MatLab libraries). And then you conclude, that MatLab should be included in the bin/debug (or bin/release) folder at compile-time. Since the MatLab library is a dependency library for Project B but not for Project A, it does not get copied and hence the exception. You can mitigate this behavior with the aforementioned Pre and Post-Build events. You can tell the Visual Studio that you want it to manually copy MatLab.dll to the output folder when it is doing a compile. This comes super handy when you come into situations like these. Build events can also trigger a lot of other things so be sure to check it out. I'm using this a lot and it's a time saver at least.
in the Visual Studio you can go Project > [project name] Properties > Reference Path
change the path/create folder or else you want
First make folder lib new project source code then use relative address
in post-build event on visual studio go to properties in your project and add this:
copy "c:\pathtolibrary\bin\debug\namelibrary.dll" "$(SolutionDir)\bin\Debug\libs"
Summary
I'm having a very strange behavior with Visual Studio 2010, and I'm not sure if it is a bug or if there is some twisted logic to why it is behaving in this way.
The executive summary is that when I use Batch Build->Select All->Rebuild to build all the configurations for all my projects, VS2010 produces differing output binaries depending on what is the currently selected Solution Configuration. This is really annoying because some of the project outputs fail to run correctly (giving a "[Project name] has stopped working" error dialog on startup) depending on which Solution configuration was selected during the batch build.
More details
I have a Solution with 3 C# projects in it (1 .dll outputting project, referenced by the other 2 .exe outputting projects). Of the .exe outputting projects, Project A has Release and Debug Project configurations. Project B has a Debug, Release-x86, and Release-x64 configuration because it needs some different post-build scripts run to give it the correct version 3rd party libraries.
I have 4 Solution Configurations: Debug, Release, Release-x86, and Release-x64. Release-x86 and -x64 are set to build only Project B. Release and Debug build Project A and the shared dll project.
If I select the Debug Solution configuration from the current configuration drop-down box, and the Batch Build all, then when I try to run the Release configuration of Project A it fails to run. If I select any other Solution configuration from the drop down, and then Batch Build all, then it runs successfully. When I diff the produced .exe file, I can see that it is different between these two cases.
Question
Is this some known intended behavior of VS2010? If so, can someone give a hint as to why this problem may be occurring and how I can fix it? Is this a bug in VS2010?
Follow-Up Clue? [Edit]
Could this have something to do with how VS2010 handles "Project references"? As I mentioned, both .exe projects reference the dll Project, call it Project D. I added that reference (to Project A, say) by selecting Add Reference -> Project -> Project D. But of course the different configurations of Project A want to use different configurations versions of Project D. When I examine the Project A -> Project D reference under Properties, I see a Path field that is not editable. Depending on which Solution configuration is selected, I either see ...\Project D\bin\Release\Project D.dll or ``...\Project D\bin\Debug\Project D.dll, and I don't see any way to control this so I guess VS2010 is trying to be smart about picking the details of Project configurations. But even more strangely, if I select Batch Build -> Select All -> Clean to remove all compiled files, than these reference paths change to ...\obj\... instead of ...\bin\... when I inspect them, and I can't seem to change them back except by removing and re-adding the project reference.
Follow-Up 2 [Edit2]
I lied a little bit earlier, I actually have 2 .dll projects (Projects D and E, say) where D references E through a project reference.
I'm pretty sure something broken or bizarre with Project References in VS2010 is the culprit, and think I have found the root cause of the selected-Solution-Configuration-dependent behavior, with the following steps
1) I Batch Build -> Select All -> Clean, to remove all previously compiled binaries.
2) I select a Debug Solution Configuration from the drop-down.
3) I Batch Build -> Select Only Project A Release -> Rebuild.
By watching the Output window, I see that VS2010 knows that Project A depends on D, and D depends on E, so it attempts to build them in reverse order. It successfully builds the Release configuration of project E. But then it tries and fails to build the Release configuration of project D, because it complains about missing the missing Debug version of E dll file. And likewise A fails to build because of the absence of the Debug version of D.
So it seems that the selection Solution Configuration is overriding the configuration of referenced projects in Project to Project references.
Is that supposed to be the case???
After some further searching, I've found that this is a known bug in VS2010, marked as "Wont Fix" by Microsoft. Batch Build in VS2010 is simply broken. If you think that's as dumb as I do, go ahead and express yourself to them.
https://connect.microsoft.com/VisualStudio/feedback/details/556158/batch-build-links-to-wrong-referenced-projects
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..