How do you determine which libraries are not being used - c#

In developing a test project I've tried a lot of things which includes declaring an enormous amount of references/libraries. As a result I have a ton of declared libraries that are not being used in my project and would like to flush them out. Is there a way to know which libraries are not in use by the end product's code? I'm hoping there is some kind of visual studio function that can tell me this.
Thanks!

Solution is handy. Just follow the link
How to: Remove Unused References
EDITED:
Since the above option is available only in VB.NET, you can go for some Visual Studio 2010 plug ins. Looks like Resharper does it. Please refer to Visual Studio: Detecting unneeded Assemblies
for more detail.

Coderush is similar to Resharper, but they offer a free Xpress version on their website. You can go download that and it should show you which are unused (although I'm not 100% the Xpress version has this ability).

You can only easily find out what assemblies are used. Easy enough to invert the list. Look at the .assembly directives that the compiler put in the assembly manifest with ildasm.exe or Reflector. The compiler whittles down the list to assemblies that contains types that it encountered while compiling the code. Watch out for assemblies you load yourself.

In Visual Studio 2019 starting from the latest versions and Visual Studio 2022 you can remove unused packages, but only for SDK style projects.
If you try on old projects, like .Net Framework, you won't see this option.
As workaround, to verify, you can create two simply console apps: one using .Net Core or later, and one .Net Framework 4.7 or 4.8.
Just right-click on project name and select Remove Unused References
Please refer to: Remove Unused References

Related

Different versions of same DLL in Multiple nuget package in Same .Net 6 Project

I have one base nuget library called Foundation.dll.
I have another 5 nuget libraries which are using a different version of Foundation.dll.
Everything is in one project.
My question is when I build a project, VS .Net is obviously going to put only one Foundation.dll in the bin/debug folder. So how VS/.Net decides which nuget package's foundation.dll should be put in the bin/debug folder. Is it randomly?
If I do reference Foundation.dll directly in the project then it is putting my direct reference version into the bin/debug folder but for some other developers in the team, it is putting an older version.
it is very scary that the same exact branch code in 2 different machines works differently. I added one argument in one of Foundation.dll's methods & for one developer it is working but for another developer, the same exact code gives a compilation error.
What is the ultimate solution to this problem? What change should I make in my project?
Thank you.
This is a difficult topic and yes, there are a lot of factors that determine which version is being put to the bin folder. Normally, the compiler chooses the latest version from all the dependencies automatically. But particularly if you have several "final" assemblies in your solution (e.g exe's, unit test libraries) the compiler sometimes gets it wrong. Usually, the code works anyway, but I agree, this is scary.
The actual outcome may depend on the build order, build environment (whether building from the command line or within VS, etc.). Me and my team has had a hard time figuring out the best way around this problem.
The safest approach we found is to reference the latest version of your package directly in the project. This does not need to be the latest version available, but the latest version used anywhere within your solution. Of course, this only works if the versions are backwards compatible. If some library requires an older version of the dependency and you can't rebuild that library, you are in for really big trouble.
I've met the same issue. One project in the solution was depending on .net standard version of a library, while others were expecting a classic framework version.
As PMF wrote, which library will finally occur in the output depends on a build order.
I've solved it by copying the .net standard version into the output folder on post-build events.
The output should not depend on random things, there's some (complex) rules for these situations:
https://learn.microsoft.com/en-us/nuget/concepts/dependency-resolution
It should choose the direct dependency over the indirect ones.
Do you still get different results when doing "rebuild all"?

Do we need to restrict the depencencies in .NET Core libraries?

I have a library written in full .NET and I am porting it to .NET Core. I intend to make it target the .netstandard1.1 (in order to be also compatible with .NET45).
When I create the project with visual studio, it automatically depends on the NETStandard.Library nuget package.
My library only needs two packages:
System.Runtime
System.Runtime.InteropServices
Two questions :
Do I need to restrict my project dependencies to only these two packages? Rephrased: may be nuget (or visual studio or another magic stuff) manage to restrict on its own to only the needed packages and not the full NETStandard.Library?
If the answer to the first question is no, is it a good idea to perform that restriction?
Thanks in advance.
(Sorry for my english, I am not a native speaker)
There are some aspects in your question...
The netstandard1.1 framework choice will limit your available API surface in the editor (here VS Code) to what is available that version. Just tested with File.OpenRead on VS Code for netstandard1.1 (not available) and netstandard1.6 (available).
The NETStandard.Library dependency (version 1.6 is good for both cases) is a package dependency. Once the assembly is compiled, the assembly itself will declare external assemblies (aka referenced assemblies) which were actually used (e.g. System.Runtime and System.Linq) and not all assemblies found in the NETStandard.Library meta package.
As long as you are not packaging it up for NuGet, assembly reference restrictions are anyway done for you. NuGet packaging however would refer to the NETStandard.Library package
If you use NuGet and that reduction is important to you, I guess the correct term is NuGet dependency trimming, a manual process explained here (short version: copy all references from the meta package and remove all you do not use).
I am not sure if it's a VS bug, however seems like VS doesn't like building a library and not having a NETStandard.Library package included :) So, no.
Unless you use Visual Studio Code or Notepad etc. this will slow down your development, since VS will prevent you from building the project etc. So, no again.
The bottom line.
Premature optimization might cause more issues than benefit. Port your library first, and only then check if you need to optimize it.

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

Can I use precompile symbol to determine which code fragment would be compiled when I switching target framework in Visual Studio

We can switch to different .NET Framework target in Visual Studio after 2008.
I have a project, and I want to build 2 different target Frameworks assembly of it.
If my target Framework is 2.0, I want it to build some code, and when I switch to another target Framework, I want it to build another code fragment to use some new functions.
now I have to manually comment and uncomment code everywhere, I wonder if I can use some precompile symbols to dynamically do this to me. Like:
#if Framework3
<do something>
#else
<do something else>
#endif
Can I?
Yes, we do this in MiscUtil. I'm not sure you can do it directly in Visual Studio, as the target framework choice is in a property page which ignores the current configuration. However, you can edit the project file directly, to get the right target framework for the right configuration. In particular, you'll want to make sure you don't have .NET 3.5 references when targeting .NET 2.0. Have a look at our main project file (MiscUtil.csproj) for more details.
The preprocessor symbol part is easy - once you've got a build configuration for .NET 2.0 you can add preprocessor symbols directly in Visual Studio.
Just define one in the build options before you compile for each framework version.
Add Framework3
Compile for .NET Framework 3.5
Change to Framework2
Compile for .NET Framework 2.0
This still isn't as automated as you probably want it to be, but it's better than uncommenting a bunch of lines, in my opinion.
Yes, you can set defined constants in the project properties. The best way to manage this, imho, is to have separate project files that share the code but have different defined constants. So a mycode_Framework1.csproj, mycode_Framework2.csproj, etc. You can have them in the same solution or not, but if you do, it makes building them all at once a bit easier.

Can't find System.Workflow assembly in .NET. How do I get it?

I've installed a complete SharePoint Server (MOSS) 2007 on my dev box + the latest Visual Studio (SP1) + the latest full Windows SDK. According to the Windows Workflow Foundation page http://msdn.microsoft.com/en-us/netframework/dd980558.aspx, that is all I should need to do to be able program against the .NET Workflow APIs.
And yet, all of the projects I build from the standard Workflow templates refer to the assembly System.Workflow and VS complains that that assembly isn't available. I've searched around on my hard drive, and I can't find a file for that assembly anywhere obvious on my disk.
I do find some files that look like they might be that assembly, but they're buried down in wacky places below particular applications like they are runtime support for that app. They don't seem to be what I'm supposed to point VS at.
Can anyone tell me how to fix this problem? Do I need to install something else that I have yet to come across? Are these assemblies already on my system and I just need to know how to point VS at them? I'm stumped.
BTW: I was going to try uninstalling and reinstalling VS, but the installer fails with some very cryptic error message when I try to uninstall.
TIA for any help, and Happy Holidays to all!!!
I did a Repair using the .NET 3.5 SP1 SDK distributable, and I believe that this solved the problem. I thought at first that it didn't (as I say in prior comments) because I was looking for the files to show up in the v3.5 assembly directory. The missing files actually go in the v3.0 assembly directory. I later brought up one of the sample projects in VC and noticed that the symbols were now resolving, and sure enough, the missing .dll files were now present.
So I guess that the .NET SDK installer that ships with VS somehow didn't install these .dll files. It took doing a Repair on the SDK to fix the problem.
I'm a happy camper now!
In addition to change the target framework to 4.0, you also need to:
Add a reference to System.Workflow.Runtime
Add a reference to System.Workflow.ComponentModel
There's no assembly named System.Workflow in .NET 3.x: the WF assemblies (in 3.x) are:
System.Workflow.Runtime
System.Workflow.ComponentModel
System.Workflow.Activities
System.WorkflowServices (3.5)
You should be able to find all these assemblies in the GAC, and reference them via the Add Reference dialog, .NET tab.
It's possible System.Workflow is a (badly named) SharePoint-specific DLL, in which case, sorry, the above won't help... try the SharePoint install directory or SharePoint SDK install directory. Are the project templates you're using SharePoint templates, or the ones from File > New Project > Visual C# > Workflow?
I have a same problem, and solved it. The reason is your project's target .net framework not include this assembly (it's maybe .net 3.5 client profile or 4.0 client profile). The solution is very simple: set the target framework of your project to .NET Framework 3.5 or 4.0.
It work for me.
Please find it in C:/Windows/Assembly/GAC_MSIL
All the DLLs are Present there..
Also If U donot Find it then do the Following
Right Click Project->Application->Target Framework-> .Net Framework 4.0
It should show Up then.

Categories

Resources