From fbd123c3d81f177f97fc35075343cfcfd5a1506f Mon Sep 17 00:00:00 2001 From: chtenb Date: Thu, 4 Sep 2025 12:29:47 +0200 Subject: [PATCH 1/4] Improve strategy for finding dot.exe --- Rubjerg.Graphviz/GraphvizCommand.cs | 30 +++++++++++++---------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/Rubjerg.Graphviz/GraphvizCommand.cs b/Rubjerg.Graphviz/GraphvizCommand.cs index faeb172..d12bd76 100644 --- a/Rubjerg.Graphviz/GraphvizCommand.cs +++ b/Rubjerg.Graphviz/GraphvizCommand.cs @@ -35,13 +35,18 @@ internal static string Rid } internal static Lazy _DotExePath = new Lazy(() => - // If graphviz is not found in the runtimes folder, look in the current directory for compatibility with nonportable windows builds. - new string[] { - Path.Combine(AppContext.BaseDirectory, "runtimes", Rid, "native", "dot"), - Path.Combine(AppContext.BaseDirectory, "runtimes", Rid, "native", "dot.exe"), - "dot", - "dot.exe" - }.FirstOrDefault(File.Exists)); + { + // Depending on the method of deployment, there are several possible directories to look for dot + string[] possibleLocations = [ + Path.Combine(AppContext.BaseDirectory, "runtimes", Rid, "native"), + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), + Path.GetDirectoryName(AppContext.BaseDirectory), + "" + ]; + return possibleLocations.FirstOrDefault(dir => File.Exists(Path.Combine(dir, "dot"))) + ?? possibleLocations.FirstOrDefault(dir => File.Exists(Path.Combine(dir, "dot.exe"))) + ?? throw new InvalidOperationException("Could not find path to dot binary"); + }); internal static string DotExePath => _DotExePath.Value; public static RootGraph CreateLayout(Graph input, string engine = LayoutEngines.Dot, CoordinateSystem coordinateSystem = CoordinateSystem.BottomLeft) @@ -74,18 +79,9 @@ public static (byte[] stdout, string stderr) Exec(Graph input, string format = " } string? inputToStdin = input.ToDotString(); - // Get the location of the currently executing DLL - // https://learn.microsoft.com/en-us/dotnet/api/system.reflection.assembly.codebase?view=net-5.0 - string exeDirectory = AppDomain.CurrentDomain.RelativeSearchPath - ?? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) - ?? Path.GetDirectoryName(System.AppContext.BaseDirectory); - - // Construct the path to the executable - string exePath = Path.Combine(exeDirectory, DotExePath); - Process process = new Process(); - process.StartInfo.FileName = exePath; + process.StartInfo.FileName = DotExePath; process.StartInfo.Arguments = arguments; // Redirect the input/output streams From c98d10e3853d0e91e1ba6b15eb23428be2201ddf Mon Sep 17 00:00:00 2001 From: chtenb Date: Thu, 4 Sep 2025 12:49:27 +0200 Subject: [PATCH 2/4] fixup --- Rubjerg.Graphviz/GraphvizCommand.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Rubjerg.Graphviz/GraphvizCommand.cs b/Rubjerg.Graphviz/GraphvizCommand.cs index d12bd76..97c4843 100644 --- a/Rubjerg.Graphviz/GraphvizCommand.cs +++ b/Rubjerg.Graphviz/GraphvizCommand.cs @@ -43,8 +43,8 @@ internal static string Rid Path.GetDirectoryName(AppContext.BaseDirectory), "" ]; - return possibleLocations.FirstOrDefault(dir => File.Exists(Path.Combine(dir, "dot"))) - ?? possibleLocations.FirstOrDefault(dir => File.Exists(Path.Combine(dir, "dot.exe"))) + return possibleLocations.Select(dir => Path.Combine(dir, "dot")).FirstOrDefault(File.Exists) + ?? possibleLocations.Select(dir => Path.Combine(dir, "dot.exe")).FirstOrDefault(File.Exists) ?? throw new InvalidOperationException("Could not find path to dot binary"); }); internal static string DotExePath => _DotExePath.Value; From c99ed5ba7dde5e1e0fcf1c08dd16f4ebf8f63809 Mon Sep 17 00:00:00 2001 From: chtenb Date: Thu, 4 Sep 2025 12:55:00 +0200 Subject: [PATCH 3/4] improve error msg --- Rubjerg.Graphviz/GraphvizCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rubjerg.Graphviz/GraphvizCommand.cs b/Rubjerg.Graphviz/GraphvizCommand.cs index 97c4843..ab56c7a 100644 --- a/Rubjerg.Graphviz/GraphvizCommand.cs +++ b/Rubjerg.Graphviz/GraphvizCommand.cs @@ -45,7 +45,7 @@ internal static string Rid ]; return possibleLocations.Select(dir => Path.Combine(dir, "dot")).FirstOrDefault(File.Exists) ?? possibleLocations.Select(dir => Path.Combine(dir, "dot.exe")).FirstOrDefault(File.Exists) - ?? throw new InvalidOperationException("Could not find path to dot binary"); + ?? throw new InvalidOperationException("Could not find path to dot binary in any of: " + string.Join(", ", possibleLocations)); }); internal static string DotExePath => _DotExePath.Value; From 37a0f53faee2c87241dab39f8a9c38428e190dad Mon Sep 17 00:00:00 2001 From: chtenb Date: Thu, 4 Sep 2025 12:57:19 +0200 Subject: [PATCH 4/4] add readonly modifier --- Rubjerg.Graphviz/GraphvizCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rubjerg.Graphviz/GraphvizCommand.cs b/Rubjerg.Graphviz/GraphvizCommand.cs index ab56c7a..ea04e92 100644 --- a/Rubjerg.Graphviz/GraphvizCommand.cs +++ b/Rubjerg.Graphviz/GraphvizCommand.cs @@ -34,7 +34,7 @@ internal static string Rid } } - internal static Lazy _DotExePath = new Lazy(() => + internal static readonly Lazy _DotExePath = new Lazy(() => { // Depending on the method of deployment, there are several possible directories to look for dot string[] possibleLocations = [