How to build a visual studio 2010 solution into a standalone dll? - c#

I have a visual studio 2010 project, uses static and dynamic libs (.lib and .dll), the project is compiled and built successfully as .exe both in release and debug modes, the code is c and c++.
What is the right way to compile and wrapping all the solution to one standalone .dll file.
I want to have one dll file, I'll be able to load it in other c, c++, c# project safely.
in my case I want to load it in teraterm and in other simple self developed c# application.

Visual Studio has a C++ linker option called "Link Library Dependencies": http://msdn.microsoft.com/en-us/library/024awkd1(v=vs.90).aspx
This would link the object files from all projects in the solution directly into the project output (via dependency tracking). Be careful when you use this though, if you use this in an EXE and the DLLs you're linking export symbols your EXE will also export them.
Update:
Here's more detail: What happens is that instead of linking the DLLs (this assumes you have the DLLs you'd like to link set as dependencies of your project in the solution) to produce separate binaries, the linker takes the outputs from each individual project dependency and links them into the final executable/DLL directly, thus creating a monolithic DLL.
A side effect is that (depending on the code) the overall size of the output is reduced a little, the monolithic DLL (or EXE) might be large in general, but smaller in size than the individual output files combined due to link-time optimisations. Any symbols exported by the objects linked will be exported by the final DLL, since they are marked as such in the compilation step.

There's may be a catch, but being in VS2010, you should just click on the startup project, select 'properties' ->
'configuration properties' -> 'general' -> 'configuration type' -> set it to 'dynamic library (dll)'

Related

C# Project - Reference .pdb for native .dll

I have a solution containing a C# Forms project that creates a UI on top of a native .dll which contains most of my program's code.
I spend most of my time working on the native code reather than C#, which means that the DLL I'm loading through my C# UI project is modified very often, and so is it's associated .pdb file which I need for debugging what I do.
However it is not possible to reference a .pdb file like one would reference a .dll, so how could I make this .pdb be copied everytime it is modified ? Adding it as an existing item is just copying it and doesn't update it when the original .pdb file gets modified.
Two only solution I see is generating the .pdb file directly into the C#'s bin/debug instead of generating it inside the native .dll project, but I'm not sure this is possible. Second solution would be to add a link to that .pdb file into the project instead of the actual .pdb file, but I'm not sure that it would work any way.
Is there a workaround to this ? I couldn't find any. Thank you.
MSVC provides Build-Events (MSVC++ 2010: project's properties -> 'Configuration Properties' -> 'Build Events' – this exists for C# and in later MSVC versions, too, possibly at another location, however). You can define pre- and post-build events there (in case of C++, pre-link events, too).
You can call shell commands, call a batch script, or (if you have installed an appropriate interpreter) event perl or python scripts. From within such a script (either as post build for the dll, copying the .pdb file away, or – what I would prefer personally – from within the C# project as pre build event).

Add reference to local folder

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"

Cascade copy of native dll resource through several projects in VS 2010

Hello I have a Project Solution consisting of several smaller projects. Those projects have dependencies to some others in the following way:
(1) Native unmanaged C++ dll with device control functions
Is used by…
(2) C# Project wrapping native functions to .Net
Is used by…
(3) Adapter wrapping to the special device to a more generally abstraction layer defined by a framework
Is used by…
(4) A simple example implementation tries to use this native device interface through the abstraction framework
Now the Problem: The native dll (1) is added to the .Net wrapper project (2) as "existing item" with "build event = content" and "copy to output… = always" as "Hans Passant" set it in this problem solution. The native dll is used in this wrapper via DllImportAttribute. And this works fine for this project. The dll will be copied to the output directory and can be found by the wrapper.
The wrapper (2) is used as "Reference" from the adapter-wrapper project (3) and also there the native dll (1) is copied to the output directory and can be found and used by the .Net wrapper (2).
BUT…
.. when I than add the adapter-wrapper project (3) to the simple example project (4) as an "Reference" the native dll (1) will not be copied to the output directory of this example project (4). So the dlls will not be found by the .Net wrapper (2) and cause a System.DllNotFoundException.
My question is: How can I make this work, that when I add the adapter-wrapper project (3) to another project, all dlls that are necessary and are in the output-directory (including the native dll (1)), are copied to the referencing projects output directory? And this without adding the native dll as resource to the example implementation as Marc Gravell saying.
Thanks a lot, J
Maybe I'm missing something, but what about changing the Output Path for each of the projects to build to a common "bin" folder?

How do I build a multiple project solution in Visual Studio without dependencies between the binaries?

I'm using Visual Studio 2010 Pro to build a solution that contains two projects. Project A contains most of my source code, while Project B is intended to run independently, but must use some of the source code contained in Project A.
Under the current configuration, Project A is contained as a reference within Project B. I'd like to be able to build and maintain versions of each project independently, but it appears that when I build the entire solution, ProjectB.exe cannot run without ProjectA.exe in the same local directory. I would think and hope that when the .exe binaries are compiled that all of their dependencies are packaged within each, but that appears not to be the case. In fact, any attempt to run ProjectB.exe while ProjectA.exe is not present results in a System.IO.FileNotFoundException.
Is there a way to build a version ProjectB.exe that runs independently and avoids code duplication?
In cases where you want common code, the best solution is to break out the common classes into a third assembly to serve as a library. (As per Adriano's suggestion.) The other option he hints at is to use the "as link" option when using the "add existing file" to the second project.
If you don't know where it is, use the "Add existing file" option, then in the dialog box to select the file, the "Add" button has a drop-down selection where you can select "As Linked File" (or something to that effect.)
This allows you to compile the same classes into multiple projects. But keep in mind that the namespacing for the linked file cannot be changed for the second project. If the namespace was "ProjectA.Domain", this is how you need to access it in Project B. This was a useful trick for Silverlight projects back before the multi-platform assemblies were introduced.
If you want to get rid or the dependency on A, you will have to extract the common logic into another project (let's call it C), as Adriano suggested in a comment.
If you need even looser bond between the projects, you can reference A (or C) not as a project, but as a built assembly (.dll file) and check Specific Version reference property to True. Additionally, if your project/codebase structure is more complex, check more assembly sharing options here.
Some options:
The common option: Separate the common code into a third class library (DLL) project. And have both ProjectA and ProjectB dependent on it. The downside is that now in order to run the projects you need two files (the main exe and the dll.) This method is how most software is developed: a single executable and a bunch of DLLs.
The correct option: Separate the common code into a third project and modify the project files to create executables that contain both assemblies (similar to statically linked libraries in unmanaged code.) The downside is that Visual Studio does not support this out of the box and you need to modify the project files which are actually MS-Build definition files to do this.
The ugly option: Create shortcuts for the common files in ProjectA in ProjectB. This is the same as copying the common code to the other project, but you're still left with one source file. The downside is that you have to do this for every file and maintain the same structure in both projects. This is an ugly, if viable, option. Choose one of the others.

How do you manage generated code in Visual Studio - in particular, creating DLLs from .idls

I'm trying to add a generated COM interop assembly project to my solution, and the only solution I could come up with feels really nasty.
I created a .net dll project, removed all .cs files from it and then created the following post-build event:
call "$(DevEnvDir)..\tools\vsvars32.bat"
midl.exe $(ProjectDir)relative-path-to-my-idl\MyComName.idl /tlb MyComName.tlb
tlbimp.exe /keyfile:path-to-my-key\k.snk MyComName.tlb
Essentially, I first create an empty DLL, then overwrite it with a real interop DLL. And there's no dependency management here - it's created every time.
Is there a better way to do this?
The MIDL compilation can be handled by making the COM interop project a managed C++ project (instead of a C# project) then adding the idl and h to the project as regular source files.
You can overcome the dependency problem by using MSBuild tasks directly instead of a PostBuild batch file, which line up nicely with the MSBuild dependency system.
However, why are you generating the file manually from an idl? When I need COM interop, I just import it and put the generated assembly (*.Interop.dll) into version control. This way, you always have the version you need and it's already ready to use, and Visual Studio can find the interop DLL before the first build, i.e. Intellisense is there right from the beginning.
Now some people won't like to check in a binary file, which I typically agree with, but well, if it works... :)
Of course, my method won't work if building the COM server is part of building the solution. In this case, just try to put the generation into the MSBuild script to get rid of the dependency thing, unless Visual Studio accepts a reference to a solution-internal non-.NET-COM project.

Categories