I want to list the assemblies in my solution, but only those which are projects in my solution rather than just a list of loaded assemblies as would be returned by AppDomain.CurrentDomain.GetAssemblies();
Is there a class that gives me run time solution information? Ideally I'm looking for something like Application.GetSolutionProjects();
Project is VS2008/C#/.Net 3.5
Thanks
The application is actually separate to your solution. You could parse the solution and project XMLs to generate a list of assemblies created by your solution.
I'm not sure how you'd do this at runtime as the solution and project files wouldn't generally be available. You could precreate a list at compile time, then have a method read it. Or you could dump your assemblies into a specific subdirectory at compile time, and just examine that directory to list your assemblies at runtime.
Solution file is just for VS, It's not a part of .net framework, and it not include in projects, i.e you can have one project and multiple solution which contains this project, you want fetch what solutions project? But, You can parse specific solution file to get all projects in the solution
Related
I have a smallish solution, with about under twenty projects. The solution used to also contain about six source projects written by a third party service provider, ACME. Now, finally, this other party is supplying us only with a handful of DLLs. I used to just included their source, one project per DLL, in the solution, and so I am looking for a neat way to include all these assemblies in the solution, so they can be referenced from the many projects that need them.
My immediately apparent options are:
Create an AcmeAssembly project, add all DLLs as project items set to copy to output.
Create an AcmeAssembly solution folder. Quicker and simpler than a 'binary-only' source project, but solution folders have the very, very large drawback of having no means of grouping the files without a solution file, i.e. outside of VS.
Create a NuGet package that includes all the required binaries. Then at least we also have a partly 'phycical' grouping in the packages folders. My problem here is I have never written a NuGet package, but I am not asking how to here. I am asking about three candidate solutions, and more will be welcome, and if NuGet wins, I get to learn to write a package.
I can't simply use the project's output bin\debug and bin\release folders. To me, these are strictly output folders, and nothing but other dependency assemblies should also be output there. Deleting the bin folder should have absolutely zero effect on a build, so that is certainly no place to store binaries.
The advantages of nuget over the other solutions are:
Support for versioning
Support is built in into Visual Studio and MSBuild
No 'magic folders' that all developers need to have on their machines
Create your Acme library folder (something like: C:\Source\Library\AcmeLibrary). Put all of your Acme dll's in that folder. Then create the Solution Folder in VS and add the existing items to it (don't add the folder, but the items in the C:\Source\Library\AcmeLibrary folder to the solution folder using "Add Existing Item..." menu selection).
I'm looking for a way to detect problems with assembly references in a large Visual Studio solution:
Binary references to bad locations, like a path not in source control or in the output of another project
Binary references to multiple versions of the same assembly across projects in the solution
Binary references without a path, that may be redirected to the GAC
Binary references that should have been project references
The whole story
I work on a large C# project with almost at 200 projects.
One of the problems that is creeping in over time is that references to assemblies are added but not always to the same version or to the correct location.
For example, a project may get a reference to System.Web.Mvc without a hint path, making it reference what ever version is in the GAC. Visual Studio (and Resharper) will also offer to add a missing reference but may do so by adding a reference to the output folder of another project.
Now the recent Windows Update catastrophy left some team members dead in the water, unable to build the solution. As you can imagine, this bumped up the priority of assembly reference management for us.
To detect some of the most obvious problems I've already setup an msbuild file that can be included in every csproj file and will detect bad references.
However, new project files will need to be edited manually to include that script. So that will inevitably be forgotten.
What I would really like is to check all project files in a solution for 'bad' references during the continuous build, so that all projects will be checked always.
I've been googling for a solution like this for some time and found lots of static analysis and code analysis tools but nothing to analyze project files in a solution.
So, before I go off and roll my own solution, is there a way to do this already?
Update
In order to clean up the code base I've created a bit of ScriptCS code that'll scan all csproj files for referenced to assemblies in Nuget packages and fix them. It's up on GitHub.
You can create a NuGet package where the sole purpose is incorporating a custom .targets file into a project. I recently used this strategy to solve another problem (error messages for missing .snk files).
Testing strong names of NuGet-distributed assemblies
Rackspace.KeyReporting source code
If you create a similar package, it's easy to right click on your solution node and verify that it is installed in all of your C# projects.
If your analysis is more complicated and requires the use of an assembly (custom build tasks) in addition to the .targets file, you can use an approach like I use for the Antlr4 NuGet package, which contains build tasks, resources, and custom .props and .targets files, but no actual assemblies that are referenced by the project it gets installed in.
ANTLR 4 C# Target source code (includes the Antlr4 package source and build scripts)
Instead of adding it to all projects in your solution, why not create some kind of test (unit test, build file, whatever) that can take a project file as input, parse it, and throw an error if OE or more references are incorrect. Much easier than adding (and checking out, committing etc) custom build steps to project files.
Even if you would use a nuget package as proposed earlier, you'd still have to check manually whether all your projects (200 projects? Really?) Reference the package.
I have some c# projects. I added post build event to those projects that copy the resulted assembly (dll) from the bin into common folder.
It appears that each compile generates assembly which is binary different from the previous even when I don't modify the project files.
It is quite a problem for me since I'm using Kiln that monitor those file and think they were modified.
I read somewhere that the dll stores time stamp of compilation which if true then I cannot fix this. If so how do you manage your shared DLL in such a way that your repository (Git/HG) doesn't commit all your compiled projects that weren't modified?
Thanks,
Eran.
To address the specific question of "How do you manage your shared DLL in such a way that your repository (Git/HG) doesn't commit all your compiled projects that weren't modified?", I have a very simple answer: ignore.
We exclude /bin and /obj from the directories which our source control will even attempt to commit. This does mean that you will need to recompile the code on each machine after each change, but Visual Studio would do that anyway for any project where the code has changed.
Don't commit the output folders of your projects.
If you want to have a Setup folder or something similar that always contains the latest versions of the assemblies created by your projects, the solution is to make sure that your post-build event is configured to run only when the build updates the project output. There is an option that is named like this:
during development of our application we use a branching structure and while we are developing another team is using earlier builds of our software to create content with it.
To facilitate easy swapping between builds and teams I was hoping to use empty Hintpaths in the content projects' csproj files so that they can use our GAC installed assemblies to build against and in the meantime add a reference path to the projects for our use during development and test cycles where we don't want any assemblies installed in the GAC.
However, it seems reference paths are not stored in the csproj file and thus don't get sourcecontrolled. Since there will be extensive branching it would be less than ideal to have to set all reference paths again when a developer pulls another branch from sourcecontrol.
I've been searching for a bit now and can't seem to find ways to do this. Anybody know of a way to force the reference path in and out of sourcecontrol?
We're talking Visual Studio 2008 and TFS 2008 here.
Cheers,
Anton.
Ok, I seem to be a little clearer in the head after a good night's sleep, took the logical step, namely investigate where exactly the information was stored and how. It turned out the information was stored in the .user file for the project in the project's folder and as it turens out this file contains mbsuild xml.
I then did what I wanted as follows:
Create the Reference path as I required it to facilitate both scenarios without any work.
Browse to the Project's .user file
Copy the PropertyGroup containing the ReferencePath
Paste the PropertyGroup in all the necessary Projects' .csproj xml.
Reload and build.
Done.
The references are stored in the *.csproj file. The nodes are ItemGroup/Reference...
Thomas
This is pretty simple--we do this in our shop.
First, in the Workspace (using Windows Explorer, browse to the Solution folder), create a folder. We name it "Referenced Assemblies". In here, drop all your DLLs.
Now, in the Solution, add a new folder to match the one created in Windows Explorer. Into that folder, add all the DLLs you just dropped in.
Finally, in each project, set up your references to use the DLLs that were added to the solution.
Now your project references DLLs that are part of the solution, so that when the build runs, it will grab the DLL from Source Control to generate the build.
Also, I'd recommend not using the GAC at all if you can avoid it. In my experience, reference behavior is strange. It seems references go first to the GAC, then to the DLL in the local folder, meaning that if the DLL is updated, the one in the GAC is used instead of the DLL in the local folder (which is likely the updated one).
I have a solution with a few projects. How I can merge all projects into a single project? I want to just compile my solution and get single file application at the output.
Note: this question has been edited for clarity. Originally it was confusing and seemed to imply that it was looking for information on merging already-compiled assemblies.
I think you're looking for ILMerge.
You want to merge the projects, not just the assemblies?
I don't know any automated process, but I think you'll want to do something like:
Create your "master" project.
Look at the .NET and binary references (not project references) that other projects have. Add each of these references to the "master" project.
Create a folder for each project that you want to merge into the master project.
For each project, copy all files from that project to the corresponding folder in the master project. Make sure you give it the same BuildAction.
Build! If the build fails, then you have more work to do.
Remove the original projects from the solution.
Does every file in each project use its own namespace? If so, the above is all you have to do that I can think of. Otherwise, you'll want to make it so, recompile, and retest before trying to merge the projects into one.
(Answer based on old interpretation of question)
I am assuming you want to merge all of the resulting assemblies into a single one, and not the projects in to a single solution.
If that is the case, use ILMerge.
From the site:
ILMerge is a utility for merging multiple .NET assemblies into a single .NET assembly. It works on executables and DLLs alike and comes with several options for controlling the processing and format of the output. See the accompanying documentation for details.
This is not the only tool - you can also use Mono.Merge for the same functionality.