Can you modify a csproj to be an empty utility project? - c#

I would like to create a .csproj for a utility project. This project has no binary output, and is just used to group a bunch of other projects into a common dependency.
I am already using .csproj inheritance and custom targets so I am very comfortable with hacking the files and having no GUI support. Does anyone have a working "empty .csproj that can be used to build only its dependencies?
I don't want people to have to install any workload other than C# Desktop. That's why I am not using a normal C++ utility project, for example. I could obviously just build something that I don't actually distribute, but it seemed like there should be a cleaner solution.
Concretely, to address all the people asking me why:
I have one DLL that's basically a core SDK
I have a bunch of DLLs that are plugins or modules on that SDK
I have a few executables, each of which doesn't know the plugins exist but of course I want them all built first when I do a "Run" on the executable
So I group all the plugins under "All plugins", plugins each require and link the SDK, and each executable just depends on "All plugins" without linking. Obviously it links the SDK. Works great. Just that the "All plugins" project is a DLL I throw away :) and that seems ugly.

Related

Understanding IlMerge - how to pack an executable with all it's associated dll's

I know I'm not the first person to ask this question on Stack Overflow and I'm sure I won't be the last. But, after spending hours researching how to do this and then physically trying to do it, I'm near ready to give up.
I have a .NET Framework 4, C#, WinForms application that builds to an executable. I rely on many many many dlls. The dlls fall into multiple categories.
Libraries I have written with no dependencies of their own
Libraries I have written with dependencies on other libraries I've written
Libraries I have written with dependencies on third party dlls
Third party stand alone dlls
Third party dlls with their own dependencies on other dlls
So after I compile my application I have a directory with an executable and approximately 15 dlls.
I want to pack all the dlls into a single executable so that I can simply distribute a single executable.
I know that IlMerge is the typically suggested application to use for this, but I'm curious if there is something easier to use that is more intuitive and works accross both WinForms and WPF.
The problem here is that ILMerge only can merge .Net assemblies. Your file lame_enc.dll isn't a .Net assembly but a standard Windows dll and therefore can't be loaded by ILMerge.
To get around this you could embed lame_enc.dll in your assembly and then extract it when needed in your application. Check out this article for more info on that.
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx
In the end, I went an entirely different direction.
I decided to use the Costura Visual Studio Extensions located here.
These extensions use a combination of two methods
Jeffrey Richter's suggestion of using embedded resources as a method of merging assemblies
Einar Egilsson's suggestion using cecil to create module initializers
What's nice here is that you simply install the extensions into Visual Studio. After doing that, for any project where you want to pack your DLLs into a single executable, simply select the project, click Project on the menu bar, Costura, Configure, and then OK. It will ask you to reload the project - click yes. Now whenever you build the project it will create just a single executable (or DLL if you are doing it on a library). Couldn't be more easy.
ILMerge only combines pure (not mixed-mode) CLR assemblies. It works by extracting all of the CIL modules and then relinking them into a single new assembly. Assembly resources are also recombined.
ILMerge cannot merge native executable code. lame_enc.dll is a native DLL file and does not contain any CIL modules, that's why you can't combine it.
If you want to pack your application into a single executable a workaround is to include lame_enc.dll as an assembly resource, then save lame_enc.dll to disk in a temp folder perhaps, and add the folder it was saved in to your application's PATH, so your [DllImport] runtime linker will be able to access it.
To address your exact issue, verify that the file C:\Release\lame_enc.dll exists and that it is in fact a .NET file. ILMerge can only merge .NET assemblies.
Now if you are only worried about distribution of your application, you may consider creating an installer to install all of the binaries, and not worry about merging them using ILMerge.
Another alternative to using ILMerge is to embed the binaries in an assembly as desribed here.

How do you go about using 'lib' folders in .Net projects for building in dependencies?

I need to get my external dll dependencies (automap, others ...) into a situation where I can build them on my build server. I would also like to get then them into subversion, so the build server can pick them up.
So I'm new to the whole 'lib' folder thing. I've searched Google, but it seems it's kind of assumed, there are no basics of what to do here. The books I own don't go into it. It's been a long time since I had a mentor at work, or even someone I could ask questions of ... and I'd really love to understand the fundamentals of what I should be doing here.
I write in .Net, use Jenkins as my CI server (new to that) and msbuild (new to that too). I'm hearing svn:externals (don't compute), NuGet ....
Please help!
Suppose my solution is called MySolution and is stored in C:\MySolution, then I have have three directories for binaries, all managed by source control.
vendor the source code of third party frameworks. If needed they are built and signed (with my key) and treated as if the code was my own. This is sometimes necessary to "fix" defects in the framework or debug their source to understand why it fails.
src\packages modules managed by nuget (I wished to combine this with my "lib" folder, but that isn't yet supported)
lib compiled libraries for which I don't have the source and that are not managed by nuget.
(I have omitted folders like "src", "sample", "setup", "documentation" and "scripts" to keep the answer specific to the OP).
The recent months I started to create my own nuget packages for "packages" in the lib folder so I can migrate all of them to "packages". Its published to a private nuget server. It also simplify managing the binaries across solutions.
I use to use externs, but they pose a branching nightmare after a while because you have to branch and pin the external dependencies to. With nuget this is no longer needed.
I would definitely avoid putting binaries in source control. You'd be far better off creating your own nuget repository containing your preferred versions of packages and either using nuget restore or some other way of "rehydrating" your dependencies for building. I use a simple batch file called nuget-update.bat which just looks at all packages.config files and gets any dependencies it finds.
It seems that you posted a sequence of questions on the same topic. I recommend NuGet, as it becomes critical and promoted hard by Microsoft. However, many old libraries are not available there, and you may still need to keep a lib folder. My open source project #SNMP is a good example,
I tried to use as many NuGet packages as possible, and even stepped up to maintain some of the dependencies, such as DockPanel Suite.

Looking for an msbuild and xbuild task to fetch referenced libraries (without nuget.exe)

I have an issue with creating an easy solution for my build system, based on mono.
Current situation is that I keep my referenced libraries inside the git repository, which is not good, for many obvious reasons.
What I want to achieve is something like what NuGet provides - automatically download dlls from the Web, put them in some directory and forget about them.
I want to do this at build time, so it would not require any additional actions with downloading libraries etc. The best option would be an msbuild (xbuild on mono) task, but I want it to be system independent, so the popular one, executing NuGet.exe, is out of question (consider parallel mono installations, etc.).
I've tried Pepita project, but it's... wrong. No, really, it is, it has too many design mistakes to be easy to use or repair. To make a proper configuration would require a serious rewrite of the whole project.
What I would love is a library, that would employ NuGet.Core library and be available as a task. If such a lib is not there, I could use any solution, that would download a nuget package and unpack it to a directory specified in .csproj.
Even better, it would be nice if such a library could resolve dependencies without specifying them explicitly in packages.config (or similar) file, e.g. if I want to include Castle.Windsor I don't want to include Castle.Core in my config file.
I know about the OpenWrap project (with NuGet Gallery), it looks promising, but I can't find the solution where I would just put a constant set of libraries in my repo once, modify csproj files, some configs and have it done.
I can tell you that OpenWrap at the core has everything built-in to do what you want. Everything you can do with the openwrap-shell is also available to be called from msbuild. So, it seems to me that you would just need to add a before build hook to call out to openwrap to perform an "update-wrap". Several months back I actually looked into doing something similar. AFAIR I actually wrote an msbuild script to call openwrap tasks, but didn't really hook them into the normal build process.
I don't know exactly what you mean with "put a constant set of libraries in your repo once"? For OpenWrap, all you need to do is maintain the "openwrap descriptor" for your project. That file contains all direct dependencies of your project (with or without restrictions on version numbers). (Indirect dependencies are pulled in automatically) Are you wondering about how you get started when you have a bunch of binary dlls to start with? I can tell you what I did. Basically, I do not use any NuGet packages, I created OpenWrap packages for everything. I also created OpenWrap packages for all our binary dependencies (some of which are open-source). This is really super simple: you fill in correct dependencies in the OpenWrap descriptor and specify that the package must only contain the given dlls. We had a bunch of binary dependencies, but once you start packaging them, it's definitely not that much work.
If you want to see an example, you can check this one:
http://code.google.com/p/ppwcode/source/browse/dotnet/External/Apache.Log4Net/trunk/Apache.Log4Net.wrapdesc
That is all you have to do to package your binary dependencies. This is a package I created and we currently use it in the company where I work. I know Log4Net is probably available as a NuGet package, and I could probably use that. The advantage of creating those binary packages myself, is that I have full control over the packages, over the version numbering of the packages, over how a big project is split over several smaller packages and so on.
As an OpenWrap repo, you can use a folder on your local filesystem, or a folder on a network share. What we use, is actually a webdav repository that we mount locally on a drive (using Windows 7). This works fine for us and also allows us to specify who has read and write access to the repository.
You mention mono.... well, that might be a problem: the currently released version of OpenWrap (2.0.2) does not run on mono AFAIK. But the good news is that Sebastien Lambla has been working hard to get OpenWrap to run on mono+xbuild for the new version that is going to be released very soon: 2.0.3. No alpha/beta builds available yet, but you can build from git. (In that case you would need to build both openwrap-shell and openwrap). Sebastien Lambla, who created OpenWrap, normally keeps an eye on questions on StackOverflow and will probably be able to give you a more complete answer on the mono status.
Btw, where I work, we are using OpenWrap already for over a year. Back then we compared both NuGet and OpenWrap, and at that moment OpenWrap was way way way ahead of NuGet. Basically, to me, NuGet was not a tool for dependency management, but a tool to assist you in Visual Studio to pull in binary dependencies from a remote server (meaning: copy dll from remote server to local folder and add reference to local dll in project file). In the mean time, NuGet has been playing catch-up with OpenWrap and has added functionality that already existed in OpenWrap. There are in my opinion only 2 things that NuGet has over OpenWrap and that is integration in Visual Studio (aka overview of remotely available packages and click-click-click adding of packages) and the fact that it is maintained by Microsoft people (AFAIK). Both things are just political: it's easier to convince people with a pretty interface and microsoft support. Personally, however, I think that OpenWrap is technically superior and I think it's really a pity that it doesn't get the attention that it deserves.

VS2010 build scripts to package DLLs into an MSI & register in the GAC

I have a requirement to package up and release a .NET control library across multiple platforms and have a question on how to automate this deployment (or make as efficient as possible) through build scripts and VS2010 configurations.
The control library is to be released as a Silverlight version (separate builds for SL 3.0, 4.0, 5.0) and WPF version (separate builds for .NET3.5 / .NET4.0). I also need to specify release and trial versions of the same libraries. Trial versions will be differentiated in code with a preprocessor statement TRIAL. Both the trial and full version will be compiled in RELEASE mode.
I'm wondering how to achieve this in the most efficient way possible. My VS2010 solution currently has one project for WPF (.NET 4.0) and one separate project for SL (SL 4.0).
Do I need to create further csproj projects for the missing versions, e.g. .NET 3.5 and SL 3.0 and 5.0?
I wish to create one MSI for all Silverlight DLLs and one MSI for all WPF dlls. Do I need to create further MSIs for the versions compiled as Trial? What about separate MSIs for each version of the .NET or Silverlight framework?
Is it possible to achieve the above deployment packaging using build.targets or build scripts?
Basically if I create manually MSIs for all the above combinations and do a full rebuild that would work, but it is also a laborious process when releasing updates. I am looking for suggestions on how to achieve this with build scripts, build.targets, MSI configurations or a combination of the above.
Finally when redistributing the control libraries, installation should ideally result in registration in the GAC.
Any comments / suggestions welcome.
Best regards,
If you are releasing for different versions of the framework, then you will need different projects. You probably could get away with switching the target framework at runtime, but there are so many variables, by the time you get them all figured out and tested, you could have easily created the additional projects.
I think it would be well worth your money to invest in an Installation tool such as Installshield that has built-in support for the rest of the functionality that you desire.
I believe that you should be able to accomplish all of your needs in a single installshield project using various switches and end user keys (to trigger trial or real installs), but you may potentially consider separating trial and real depending on your licensing scheme.
Update
You can also solve this issue through a pure VS2010 solution, it's just more complicated.
Based on your goals, you will need to have a total of 5 projects and each solution will have 2 configurations, one for release one for trial (where the preprocessor define is set).
You might be able to get away with a single build solution that contains all 5 projects since you can reference the output from each project separately within the VS setup project.
On release, you will have to run the build twice, once for release and once for trial, but you can easily automate this with MSBuild.
What we did to ease the release process burden was create a small database to hold configuration information about the products (locations of solutions, project files, and assemblies) and a small UI application that builds the apps by first changing the version everywhere necessary and then building the installer solution through the visual studio build process.
One very important note that I just remembered as I was typing the above: at one point (it may have been fixed), it was not possible to build Visual Studio 2010 setup projects through MSBuild, which is why we went with building through devenv.com.
For posterities sake I'm recording the solution I came up with thanks to competent_tech's very informative answer.
Solved using an msdos batch file as follows.
Dumped the idea of #If Trial switch. Instead component is licensed by licx file so trial build is the same as release build. This means just one solution for dev work which build outputs are derived from
Created a batch file to rebuild Silverlight and WPF output projects with MSBuild, switching toolsversion to create multiple versions
Copied DLLs over to Nuget style directory structure, e.g. Build/lib/net40, Build/lib/sl4, Build/lib/sl5 etc...
Obfuscate built libs in place
XCopy example projects over to Build/examples/
Use Powershell to edit example projects to reference new obfuscated output.
For reference, please see the following questions and answers on removing/re-adding references and editing project files with powershell

Open Source projects with dependencies

I have a question regarding c# open-source projects and dependencies. For example, I am currently working on a few projects. One is a C# project that produces a class library with specific functionality. This project should be hosted as other projects will find this functionality useful.
The next project I'm working on requires a reference to the class library project which is under separate version control.
So how can I structure an open-source c# project with a dependency to the class library project without including the source code of the class library project?
Any example projects to study would be great too! :) Thanks in advance!
If the open source depency is on listed on Nuget then the easiest way is to add the Nuget package, and make sure your packages folder and packages config file is included in the project.
Unless you want the actual source, then this is the easiest way to add binary dependencies. It includes the PDBs so you get the lines of the original source code.
Include a cmake script to gather dependencies in the application source code. The cmake script will check for dependencies, and any that are missing will be downloaded.
You could experiment with the cmake script being a pre-build step in the solution; But for now dependencies are updated manually.
The script is the same no matter which system it is on, which is the beauty of cmake's script mode.
Although this is a bit clunky, it seems about the best way to include a source-code version of an external dependency which is not a part of the applications version control.
as an example, you can get a launchpad project:
bzr branch lp:~brian-sidebotham/+junk/valverschatcam
from the root of this project, simply run:
cmake -P build.cmake
Obviously the script should probably be called deps.cmake or similar instead of build right now.

Categories

Resources