Is there a way, either textual or graphical, to view the hierarchy of dependencies between NuGet packages?
If you're using the new .csproj, you could get all dependencies with reference in here (after project built):
{ProjectDir}\obj\project.assets.json
Like #neil-barnwell solution, but works with NuGet.Core 2.7+
Install-Package NuGet.Core
Here is the code
using System;
using System.Linq;
using System.Runtime.Versioning;
using System.IO;
using NuGet;
public class Program
{
public static void Main(string[] args)
{
var frameworkName = new FrameworkName(".NETFramework, Version=4.0");
// var packageSource = "https://www.nuget.org/api/v2/";
var packageSource = Path.Combine(Environment.GetEnvironmentVariable("LocalAppData"), "NuGet", "Cache");
var repository = PackageRepositoryFactory.Default.CreateRepository(packageSource);
const bool prerelease = false;
var packages = repository.GetPackages()
.Where(p => prerelease ? p.IsAbsoluteLatestVersion : p.IsLatestVersion)
.Where(p => VersionUtility.IsCompatible(frameworkName, p.GetSupportedFrameworks()));
foreach (IPackage package in packages)
{
GetValue(repository, frameworkName, package, prerelease, 0);
}
Console.WriteLine();
Console.WriteLine("Press Enter...");
Console.ReadLine();
}
private static void GetValue(IPackageRepository repository, FrameworkName frameworkName, IPackage package, bool prerelease, int level)
{
Console.WriteLine("{0}{1}", new string(' ', level * 3), package);
foreach (PackageDependency dependency in package.GetCompatiblePackageDependencies(frameworkName))
{
IPackage subPackage = repository.ResolveDependency(dependency, prerelease, true);
GetValue(repository, frameworkName, subPackage, prerelease, level + 1);
}
}
}
It is also possible to write code against the API in NuGet.Core. Install it via NuGet:
install-package nuget.core
Then you can get a repository object and walk the graph. Here's a sample app I just built:
using System;
using System.Collections.Generic;
using System.Linq;
using NuGet;
namespace ConsoleApplication2
{
class Program
{
static void Main()
{
var repo = new LocalPackageRepository(#"C:\Code\Common\Group\Business-Logic\packages");
IQueryable<IPackage> packages = repo.GetPackages();
OutputGraph(repo, packages, 0);
}
static void OutputGraph(LocalPackageRepository repository, IEnumerable<IPackage> packages, int depth)
{
foreach (IPackage package in packages)
{
Console.WriteLine("{0}{1} v{2}", new string(' ', depth), package.Id, package.Version);
IList<IPackage> dependentPackages = new List<IPackage>();
foreach (var dependency in package.Dependencies)
{
dependentPackages.Add(repository.FindPackage(dependency.Id, dependency.VersionSpec.ToString()));
}
OutputGraph(repository, dependentPackages, depth += 3);
}
}
}
}
In my case, this app outputs something like this:
MyCompany.Castle v1.1.0.3
Castle.Windsor v2.5.3
Castle.Core v2.5.2
MyCompany.Common v1.1.0.6
CommonServiceLocator v1.0
MyCompany.Enum v1.1.0.7
MyCompany.Common v1.1.0.6
CommonServiceLocator v1.0
MyCompany.Enum v1.1.0.7
MyCompany.Enum v1.1.0.7
MyCompany.Versioning v1.3
Castle.Core v2.5.2
Castle.Windsor v2.5.3
Castle.Core v2.5.2
CommonServiceLocator v1.0
NUnit v2.5.10.11092
RhinoMocks v3.6
I've found a nice NPM package to print the dependency tree into console. Of course if you don't mind using/installing NPM/Node.JS.
Considering other solutions, this is the most simple one, you don't need to write your own code or register something, and you get just such dependency tree as you expect. But it works only with packages.config format.
I can't believe this functionality is absent in free Visual Studio editions or nuget.exe too.
I Can Has .NET Core (GitHub repository) produces nice graphs of NuGet dependencies along with a Graphviz representation. And as its name implies, you also get .NET Core compatibility information for free.
If you prefer to run it locally on your computer, I Can Has .NET Core also offers a console mode.
I add a compatible solution with the latest version of nuget-core
install-package nuget.core
This is the console App to get the dependencies graph
class Program
{
static void Main()
{
Console.Write("Enter the local repo folder: ");
var repoFolder = Console.ReadLine();
var repo = new LocalPackageRepository(repoFolder);
IQueryable<IPackage> packages = repo.GetPackages();
OutputGraph(repo, packages, 0);
}
static void OutputGraph(LocalPackageRepository repository, IEnumerable<IPackage> packages, int depth)
{
foreach (IPackage package in packages)
{
Console.WriteLine("{0}{1} v{2}", new string(' ', depth), package.Id, package.Version);
IList<IPackage> dependentPackages = new List<IPackage>();
foreach (var dependencySet in package.DependencySets)
{
foreach (var dependency in dependencySet.Dependencies)
{
var dependentPackage = repository.FindPackage(dependency.Id, dependency.VersionSpec, true, true);
if (dependentPackage != null)
{
dependentPackages.Add(dependentPackage);
}
}
}
OutputGraph(repository, dependentPackages, depth + 3);
}
}
}
Package Visualized from NuGet 1.4 should work. See http://docs.nuget.org/docs/release-notes/nuget-1.4
Since this is an old question, it is important to note the following:
This is a built-in feature in the new csproj format. In Visual Studio 2017 and up, open the Solution Explorer and you can find you packages like:
{Your project}->Dependencies->Packages
You can open each NuGet dependency tree and run with it recursively, effectively seeing not only the dependency tree for specific packages, but also which NuGet packages your project actually installs.
Another option you have is to use the nuget-deps-tree npm package.
It supports both the packages.config format and the newer assets format used by .NET projects.
FYI, MyGet.org has this kind of visualization built-in. You can view dependency graphs on the Feed Details page.
https://github.com/mikehadlow/AsmSpy using this to identify assembly version across a project
Microsoft will deprecated support of Classic API for Service Bus at November 2021 (as described here)
In our code we use WindowsAzure.ServiceBus package.
It is an ol package and Microsoft suggets to use new Azure.Messaging.ServiceBus package.
WindowsAzure.ServiceBus package contain GetQueues(String) method. This method can use filter parameter for filtration queues by name or properties. It is very useful if a ServiceBus has many Queues.
But I can't find equivalent of this feature in new Azure.Messaging.ServiceBus package.
How can I implement filter feature in new package?
Thanks for any help.
How can I implement filter feature in new package?
You will need to use GetQueuesAsync method in ServiceBusAdministrationClient class to get this information.
Please see the sample code:
using System;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus.Administration;
namespace SO67703647
{
class Program
{
static string connectionString = "your-connection-string";
static async Task Main(string[] args)
{
var adminClient = new ServiceBusAdministrationClient(connectionString);
var queuesListingResult = adminClient.GetQueuesAsync();
await foreach (var item in queuesListingResult)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("=======================");
Console.WriteLine("Press any key to terminate the application.");
Console.ReadKey();
}
}
}
I have these requirements coming from client every week for some new logic or verification. For which I have to code new logic (basically some if-else and loops) and launch a new build for him. I want to avoid it by simply coding my logic in visual studio then writing a utility to export it to XML or something and send it to client via e-mail. He just have to place this file in some appropriate folder and the application will behave considering this logic.
Please suggest some solutions. My platform is C# Asp.Net.
Thanks
Using .NET 4.6 and the NuGetPackage Microsoft.CodeAnalysis.Scripting you could implement a scripting engine to run your c# code residing in a textfile without building an assembly.
Install NuGet Package:
Install-Package Microsoft.CodeAnalysis.Scripting.CSharp
Implement TestClass with some basic C#-Code-Content:
class Program
{
static void Main(string[] args)
{
TestScript();
}
private static async void TestScript()
{
// Code snippet: a class with one string-property.
string codeContent = #" using System;
public class ScriptedClass
{
public string HelloWorld { get; set; }
public ScriptedClass()
{
HelloWorld = ""Hello Roslyn!"";
}
}
new ScriptedClass().HelloWorld";
// Instanciate CSharpScriptEngine
var engine = new CSharpScriptEngine();
// Execute code and return string property (HelloWorld)
var scriptingState = await engine.ExecuteAsync(codeContent);
// Print return value from CSharpScript
Console.WriteLine("Returned from CSharpScript: {0}", scriptingState.ReturnValue);
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
}
Implement a ScriptingEngine:
internal sealed class CSharpScriptEngine
{
public async Task<ScriptState<object>> ExecuteAsync(string codeContent)
{
// Add references from calling assembly
ScriptOptions options = ScriptOptions.Default.AddReferences(Assembly.GetExecutingAssembly());
// Run codeContent with given options
return await CSharpScript.RunAsync(codeContent, options);
}
}
Read ScriptCode from textfile:
So basically you could read some csharpcode from a textfile of your choice and run them on the fly:
private static async void TestScript()
{
// Read in script file
string codeContent = File.ReadAllText(#"C:\Temp\CSharpScriptTest.cs");
var engine = new CSharpScriptEngine();
// Run script
var scriptingState = await engine.ExecuteAsync(codeContent);
Console.WriteLine("Returned from CSharpScript: {0}", scriptingState.ReturnValue);
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
In case you are wondering how all of this works under the hood, Roslyn will create a so called submission from your script code. A submission is an in memory assembly containing the types generated around your script code, which can be identified among the assemblies in the current AppDomain by a ℛ prefix in the name.
The precise implementation details are not important here (though, for example, scriptcs heavily relies on understanding in detail how Roslyn works to provide its extra features), but it's important to know that submissions can be chained together. When they are chained, variables, methods or classes defined in an earlier submission are available to use in subsequent submissions, creating a feature of a C# REPL (read-evaluate-print loop).
C# and Visual Basic - Use Roslyn to Write a Live Code Analyzer for Your API
Hope it helps
Now, I upgrade my web application from .NET4.0 to 4.5.2.
In my app, I use Ajax.Pro.dll.
In aspx.file, call ajaxMethod like follow by javascript.
function callAjax() {
ajaxClass.ajaxMethod();
}
In cs.file there are ajaxMethod like follow.
class AjaxClass
{
[AjaxPro.AjaxMethod]
public void AjaxMethod()
{
this.textBox.text = "AjaxCalled!!";
}
}
In .NET4.0, My app ran completely. But in .NET4.5, ajaxClass is null.
Is Ajax.Pro.dll used in .NET4.5?
Please answer my problem.
I am using the following code under ASP.NET 4.0 framework to obtain the version of MSI file from a web app:
string strVersion = "";
try
{
Type InstallerType;
WindowsInstaller.Installer installer;
InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);
WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);
WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");
WindowsInstaller.Record record = null;
dv.Execute(record);
record = dv.Fetch();
strVersion = record.get_StringData(1).ToString();
dv.Close();
//db.Commit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
//Failed
strVersion = "";
}
It works fine except that when the code finishes running it holds an internal MSI file handle so when I try to move or rename the MSI file I get the error that the file is still in use. This continues until I actually navigate away from the ASPX page that calls the method above.
My question is, I obviously didn't close some handle or object in the code above. But what could that be?
PS. I'm testing it in a development IDE from VS2010.
EDIT: Edited the code like it should be after Adriano's suggestion. Thanks!
The COM object has not been released (it should be auto-released when it goes out of scope but in .NET this doesn't work really well). Because it does not implement the IDisposable interface you can't call its Dispose() method and you can't use it inside an using statement. You have to explicitly call Marshal.FinalReleaseComObject. For example:
try
{
// Your stuffs
}
finally
{
dv.Close();
Marshal.FinalReleaseComObject(dv);
Marshal.FinalReleaseComObject(db);
}
Moreover note that you do not really need a call to the Commit() method because you didn't make any change but just a query.
FWIW, you should be using Windows Installer XML (WiX) Deployment Tools Foundation (DTF). It's an FOSS project from Microsoft that can be found on CodePlex. It has MSI interop libraries with classes that are very similar to the COM classes but implement IDisosable and use P/Invoke instead of COM behind the scenes. There is even support for Linq to MSI if you want. And the full source code is available.
DTF is the gold standard for MSI interop in a .NET world. Here are two examples:
using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Linq;
namespace ConsoleApplication3
{
class Program
{
const string DATABASE_PATH = #"C:\FOO..MSI";
const string SQL_SELECT_PRODUCTVERSION = "SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'";
static void Main(string[] args)
{
using (Database database = new Database(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecuteScalar(SQL_SELECT_PRODUCTVERSION).ToString());
}
using (QDatabase database = new QDatabase(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
var results = from property in database.Properties where property.Property == "ProductVersion" select property.Value;
Console.WriteLine(results.AsEnumerable<string>().First());
}
}
}
}
try to Dispose the Objects.
dv.Dispose();
db.Dispose();