So I’ve created a project that uses the Newtonsoft.JSON package. When I do a build (wether debug or release) the dll file gets put in the output folder.
However I’ve used Microsoft’s Dependency walker to see what other dll’s I need to ship etc and I can not find a trace of the Newtonsoft.JSON dll anywhere in there.
So this leads me to the question, how can I know what dependency files my project needs? In Delphi I could the DWalker to see what bpl files to distribute but I do not know how to do that for a .NET project. Is there some other tool I need to use ?
I add the following code to the startup of the application:
if Debugger.IsAttached then
begin
var assemblyList := new List<String>;
AppDomain.CurrentDomain.ProcessExit += method (sender: Object; e: EventArgs)
begin
assemblyList.Sort();
File.WriteAllLines('UsedAssemblies.txt', assemblyList);
end;
AppDomain.CurrentDomain.AssemblyLoad += method (sender: Object; args2: AssemblyLoadEventArgs)
begin
assemblyList.Add(args2.LoadedAssembly.FullName);
end;
end;
This can be added to the Main method (console or winforms) or the App.OnStartup method (WPF)
When starting the app in Visual Studio this code will be activated,
If you then use the software and go through all of the functions, when you close the application a file named “UsedAssemblies.txt” is created in the exe folder.
That file contains all the assemblies that you app has loaded during the previous execution.
Thanks for that. I’ve added it as a class method so that I can use it every program I do.
Is this the only way though? No seperate program to analyse the final exe ?
namespace DependencyChecker;
interface
uses
System.Collections.Generic,
System.Linq,
System.Reflection;
type
ConsoleApp = class
private
class fUsedAssemblies: HashSet<&Assembly> := new HashSet<&Assembly>;
public
class method Main(args: array of String);
class method ProcessAssembly(aAssembly: &Assembly);
end;
implementation
uses
System.IO;
class method ConsoleApp.Main(args: array of String);
begin
if args.Length < 1 then exit;
if not File.Exists(args[0]) then exit;
var dirName := Path.GetDirectoryName(args[0]);
AppDomain.CurrentDomain.AssemblyResolve += method (sender2: Object; args2: ResolveEventArgs): &Assembly
begin
var fn := dirName + Path.DirectorySeparatorChar + args2.Name + '.dll';
if file.Exists(fn) then
begin
exit &Assembly.LoadFile(fn);
end;
fn := dirName + Path.DirectorySeparatorChar + args2.Name + '.exe';
if file.Exists(fn) then
begin
exit &Assembly.LoadFile(fn);
end;
end;
var initialAssembly := &Assembly.LoadFile(args[0]);
ProcessAssembly(initialAssembly);
for each asm in fUsedAssemblies do
begin
Console.WriteLine(asm.ToString());
end;
Console.ReadLine();
end;
class method ConsoleApp.ProcessAssembly(aAssembly: System.Reflection.Assembly);
begin
if aAssembly.FullName.Contains('b77a5c561934e089') then exit;
if aAssembly.FullName.Contains('b03f5f7f11d50a3a') then exit;
if aAssembly.FullName.Contains('31bf3856ad364e35') then exit;
fUsedAssemblies.Add(aAssembly);
var refAsms := aAssembly.GetReferencedAssemblies();
for each asmName in refAsms do
begin
var asm := &Assembly.LoadWithPartialName(asmName.Name);
if assigned(asm) then
if not fUsedAssemblies.Contains(asm) then ProcessAssembly(asm);
end;
end;
end.
This is a command line app, just pass the path+name of the app as a param to this app and it should give you all the dlls it uses.
My initial tests seems to indicate that it works, but it is a quick and dirty approach…
It keeps crashing
First it wanted the full path, so I entered that.
Now it crashes on trying to find PresentationFramework with a file not found exception.
I think for now I will use your other method (the one baked right into the program itself). That works and it gives me the assemblies it uses, I just have to remember to switch it off LOL.
BTW: Why do you dismiss these assemblies ?
if aAssembly.FullName.Contains('b77a5c561934e089') then exit;
if aAssembly.FullName.Contains('b03f5f7f11d50a3a') then exit;
if aAssembly.FullName.Contains('31bf3856ad364e35') then exit;
Yeah like I said, it was something I quickly created yesterday…
Concerning the first way that I suggested, you don’t have to turn it off, because when running outside Visual Studio that code will not be invoked…
I dismissed those assemblies because that are all the framework assemblies. You don’t need to deploy those because they are included in the .NET framework.