I have a collection of unmanaged dlls with a C# wrapper around them that I'm calling from a C# project. I've added a build event line that looks like:
mkdir ..\Release
mkdir ..\Debug
copy ..\..\Includes\*.dll ..\Release\*.dll
copy ..\..\Includes\*.dll ..\Debug\*.dll
Problem is, when I go to publish the application, those dlls aren't included, and the publication is worse than useless, since it creates an application that runs until you call one of those dlls.
So, how do I include unmanaged dlls when I publish the project?
And the answer is: don't publish this, use the windows installer instead, as described here.
I'm currently investigating the same issue. The literature on the topic is very sparse indeed!
The only solution I can see is to embed the unmanaged DLL as an embedded resource inside the assembly, and programatically extract it out to the executing path before calling any functions.
Related
So I have a web application in Visual Studio 2010. Im depending on 2 DLLs. One of these are not a "real" DLL but a COM object. The first DLL is wrapper for this COM object.
So the first DLL is easy to add with a reference and when I deploy it gets put in the bin folder on the destination. The problem is the COM DLL. I can not add it as a reference. So I tried the accepted answer on this How do you include additional files using VS2010 web deployment packages? but I could not make it work. (some comment suggest this edit should be in the .pubxml file but i don´t even have that one?)
I also tried the second answer on the same question but still no luck.
The only thing that works if I go to the project properties and select "all files in this project" but I really don´t like that.
I know these answers I refer to are a bit old so maybe there is a new way of doing this?
I have experienced a similar situation in the past. The only viable way around I have found was to manually copy the files I needed when building the application using the "Build Events" screen (Go to "My Project" > "Compile". It is a the bottom right hand corner).
In the "Post-build event command line", I have entered a script that copies the DLLs I need into the bin folder of my web app:
XCOPY "E:\ThirdParty\Example.dll" "$(TargetDir)" /Y /R
This script simply copies the dll "Example.dll" from a repository folder into the bin folder of the web app I am compiling. You can find a lot more about these build events on MSDN: https://msdn.microsoft.com/en-us/library/ms165412.aspx
Hope this solves your problem and good luck!
I managed to work it out. I found this http://sedodream.com/2012/06/15/VisualStudio2010WebPublishUpdates.aspx page and installed the update for web publishing.
After that I had the pubxml files and I edited it according to the guidelines.
As found on http://www.asp.net/mvc/overview/deployment/visual-studio-web-deployment/deploying-extra-files
Summary
I want to alter the build process of a 2-assembly solution, such that a call to ILMerge is invoked, and the build results in a single assembly. Further I would like to be able to debug into the resultant assembly.
Preparation - A simple example
New Solution - ClassLibrary1
Create a static function 'GetMessage' in Class1 which returns the string "Hello world"
Create new console app which references the ClassLibrary.
Output GetMessage from main() via the console.
You now have a 2 assembly app which outputs "Hello World" to the console.
So what next..?
I would like to alter the Console app build process, to include a post build step which uses ILMerge, to merge the ClassLibrary assembly into the Console assembly
After this step I should be able to:
Run the Console app directly with no ClassLibrary1.dll present
Run the Console app via F5 (or F11) in VS and be able to debug into each of the 2 projects.
Limited Success
I read this blogpost and managed to achieve the merge I was after with a post-build command of...
"$(ProjectDir)ILMerge.bat" "$(TargetDir)" $(ProjectName)
...and an ILMerge.bat file which read...
CD %1
Copy %2.exe temp.exe
ILMerge.exe /out:%2.exe temp.exe ClassLibrary1.dll
Del temp.exe
Del ClassLibrary1.*
This works fairly well, and does in fact produce an exe which runs outside the VS environment as required. However it does not appear to produce symbols (.pdb file) which VS is able to use in order to debug into the code.
I think this is the last piece of the puzzle.
Does anyone know how I can make this work?
FWIW I am running VS2010 on an x64 Win7 x64 machine.
Update: Why do I want to do this?
It's been asked: 'Do I really need to ILMerge during the debug scenario?'
The assemblies of my solution will need to coexist in the same folder as those of other solutions (some of which I will likely develop)
Some of these solutions will share dependencies on different versions of some assemblies.
So Solution1 might be made up of Console1 and ClassLibrary1.dll(v1) and Solution2 might be made up of Console2 and Classlibrary1.dll(v2).
Rather than register everything in the GAC, I thought I could ILMerge the correct version of a dependency into the primary assembly of the solution to avoid a collision.
However this currently renders it impossible to debug the solution, which I need to do in place in conjunction with the other solutions which will be present.
Does this sound complicated? That's because it is.. :D
I'm sorry you're having problems. I didn't follow your exact steps, but I created a console application, A.exe, that called a method in a dll, B.dll. I built both assemblies in Debug mode (so that they had PDB files). I then merged them like this:
ilmerge /out:foo.exe A.exe B.dll
(Actually A and B were in another directory so my command line was a little more complicated, but that shouldn't make a difference.) After ILMerge completed, there were two files in the current directory: foo.exe and foo.pdb. I then typed:
devenv foo.exe
This opened up Visual Studio and then I hit "F10" to start the debugger. I was able to step into the Main method in the executable and then used "F11" to step into the method in that had originally been in B.dll. The debugging experience was just the same as it had been in the original Visual Studio solution with the two assemblies.
If you are still having problems, please feel free to put your entire solution into a zip file and send it to me (mbarnett at microsoft dot com) and I can try it out.
I would suggest that you only ILMerge release builds of your assemblies. I can't imagine any benefit you'd get from merging debug assemblies.
I tried to do something like this and found that you should not rename anything, neither before not after the merge. Moving stuff to to separate directory is fine. If you do not rename anything, it works.
If you are still using ILMerge, like I am, there is also an another solution to debugging issues. At least for me the dubugging started working after NOT using the portable PDB format. My project is .NET Standard 2.0 and I was running it under .NET Framework.
I don't think ILMerge can do it. OTOH smartassembly from red-gate (not free) can do it, at least so it says at features
And yes, I do agree with Mike to only use ILMerge for release versions.
Maybe that's silly, but I'm confused again when trying to find appropriate names for my projects.
I have a solution with two projects. First project is a library, which will be used by other libraries in the future, for creating plugins for my app. Second project is a exe, which uses first project to create GUI and do some stuff, eg. load plugins.
In similar situation, when one project is a dll and second is an exe, how do you choose names for each project?
Lets say, that I would like to peek a name GraphDemonstration. The exe should be GraphDemonstrationGUI and dll - GraphDemonstration? But exe is not just a GUI. So maybe GraphDemonstration for exe and GraphDemonstrationLib for dll?
I have had similar situation in the past. Maybe there is some kind of naming convention? I don't even know if my "problem" is related to VS only.
GraphDemonstration for your EXE is fine because it describes the purpose of the EXE. However, you said the library will be used by other projects later so the "GraphDemonstration" part of GraphDemonstrationLibrary may not be the best choice. Perhaps GraphLibrary, or GraphHelper, or maybe more specific depending on what is actually included in the library. For example, if the library handles instantiating an Excel object to generate a graph you could call it ExcelGraphHelper.dll.
If this is library of main class CSomeClass I name project SomeClassLibrary.
For projects smillary but non from main object.
I am using VSTS Unitesting platform. I am trying to test a method which got references to assemblies which in turn contain DllImport to C++ DLLs.
In order for it to work I need to copy C++ DLLs to reside on the same directory the EXE and DLLs are running.
Of course when I use the same code with Unittest I also need to supply those DLLs.
I found out that the Unittest framework us using the $(Solution)\TestResults[WorkSpace] [DateTime]\Out as a working directory.
If I manually copy the C++ DLLs to this directory the unit test is is working like a charm.
The problem is that every time the Unitest is running it creates a new directory.
Has anybody encountered it? do you have a solution?
Thanks,
Ariel
As Steve D mentions, deployment items are the answer here. You can either put them on the class, or test method using the attribute, or use the Test Run Configuration to add them so that when any tests are run from that solution they will be deployed.
The other option is to make sure they're in the path somewhere so that the standard windows look up rules for DLLs will apply, and the runtime will be able to locate them.
Why is this a problem? because theres little to no metadata from the project to the Native DLL -- we don't know to pick it up. The only option really would be to dive all types in the deployed managed dlls looking for the DllImport attrib. This would, however, fail, if you are doing explicit DLLLoads in the managed code.
You could try using a [DeploymentItem] attribute. It allows you to specify a relative path from the solution file which will get copied to the test output directory.
Let's say you have a class library project that has any number of supplemental files that also need to be included with the compiled assembly (e.g. simple text files or even a legacy unmanaged DLL that's wrapped by the assembly as an interop layer). While embedding the supplemental files into the assembly itself is relatively straightforward, we have situations where this is not possible or just undesirable. We need to have them as "sidecar" files (i.e. files alongside the assembly, potentially in subdirectories relative to the assembly)
Adding those files to the project with an appropriate value for "Copy to Output Directory" specified appears to be sufficient for projects that are completely self-contained within a solution. But if a separate project in another solution adds a reference to the assembly, it does not automatically pickup its sidecar files. Is there a way in the project to somehow mark the resulting assembly such that anything referencing the assembly will also know it needs to include the associated sidecar files? How do you do this?
You can use al.exe, but there also appears to be a C# compiler option. You want to create a multifile assembly using the /linkresource C# compiler option. Instructions are here, but the command is similar to this:
csc /linkresource:N.dll /t:library A.cs
Where N.dll is a native DLL that will go wherever the managed assembly goes (including into the GAC.) There's a very clear description at the link I provided.
Have you tried creating a setup for your solution ? There's an option of including sidecar files targeting to application installation directory.
Another option would be to include the sidecar files in the Assembly resources and un-wrap them to disk when run for the first time.
What if you create a merge module containing the library plus its dependencies? Your installer will then need to reference this module, but you will ensure all of the necessary files will be present.
Unfortunately there doesn't appear to be a lot of built-in support in Visual Studio for this, although I can definitely see the use case.
If you use Subversion for your source control, then you could link in an external reference as an externals definition. This would bring in the source code, and you'd be making a reference to the necessary assembly as a project reference instead of a DLL reference, and then the copy to output directory rules would come into play.
If that's not possible, another solution would be to include commands in the pre/post-build events of your in-solution project to copy the most up-to-date sidecar files from the remote assembly on a build. Of course this comes with the caveat that it doesn't set itself up automatically when you include the DLL in your project; you have to take manual steps to set it up.
I deal with this some time ago. Its a common problem.
You can create some postbuild actions:
http://www.codingday.com/execute-batch-commands-before-or-after-compilation-using-pre-build-or-post-build-events/
Hope this helps... :)
It appears to me that you're using the wrong type of reference. There are two types of references- Reference and ProjectReference. Reference is an explicit reference to a specific assembly. ProjectReference is a reference to another project (say .csproj).
What you're looking for is ProjectReference. VS and the default MSBuild targets are setup to do CopyLocal. If you set CopyToOutputPath true for your "sidecar" files, any ProjectReferences to this project now will also pull in the same files.
I'm not sure if you can to ProjectReferences across solutions in the IDE. I deal a lot with MSBuild where sln files are not relevant and this is how I deal with it.
What we did in our project is that we created as separate build file to do all those stuffs.
In your build file you can have tags to build your main solution, then add tags to copy files you need after build.
NAnt is also your option, but right now I'm happy using Rake as my build/debug automation.
Since this cannot be integrated within Visual Studio, what I'm doing is I create a task (either in MSBuild, NAnt or Rake), that executes vsjitdebugger.exe in the end to attach it to my Visual Studio when debugging.
These are just my styles for now, you can maybe create your own style.