Forge
csharpdeeb25a2
1#nullable enable
2using System.Diagnostics;
3using System.IO;
4using CascadeIDE.Contracts;
5
6namespace CascadeIDE.Features.Os.DataAcquisition;
7
8[IoBoundary]
9public interface IOsShellLauncher
10{
11 void TryOpen(string target, Action<string>? onError = null);
12 void TryOpenDirectory(string directoryPath, Action<string>? onError = null);
13 void TryOpenUrl(string url, Action<string>? onError = null);
14 void TryRevealFile(string filePath, Action<string>? onError = null);
15}
16
17/// <summary>
18/// DAL: centralized OS-shell interactions (open path/url with default handler).
19/// Cross-feature dependency point for "ask OS to open something".
20/// </summary>
21[IoBoundary]
22public sealed class OsShellLauncher : IOsShellLauncher
23{
24 public void TryOpen(string target, Action<string>? onError = null)
25 {
26 if (string.IsNullOrWhiteSpace(target))
27 return;
28
29 try
30 {
31 Process.Start(new ProcessStartInfo
32 {
33 FileName = target,
34 UseShellExecute = true
35 });
36 }
37 catch (Exception ex)
38 {
39 onError?.Invoke(ex.Message);
40 }
41 }
42
43 public void TryOpenDirectory(string directoryPath, Action<string>? onError = null) =>
44 TryOpen(directoryPath, onError);
45
46 public void TryOpenUrl(string url, Action<string>? onError = null) =>
47 TryOpen(url, onError);
48
49 public void TryRevealFile(string filePath, Action<string>? onError = null)
50 {
51 if (string.IsNullOrWhiteSpace(filePath))
52 return;
53
54 try
55 {
56 var full = CanonicalFilePath.Normalize(filePath);
57 var dir = Path.GetDirectoryName(full);
58 if (string.IsNullOrWhiteSpace(dir))
59 {
60 TryOpen(full, onError);
61 return;
62 }
63
64 if (OperatingSystem.IsWindows())
65 {
66 Process.Start(new ProcessStartInfo
67 {
68 FileName = "explorer.exe",
69 Arguments = $"/select,\"{full}\"",
70 UseShellExecute = true
71 });
72 return;
73 }
74
75 if (OperatingSystem.IsMacOS())
76 {
77 Process.Start(new ProcessStartInfo
78 {
79 FileName = "open",
80 Arguments = $"-R \"{full}\"",
81 UseShellExecute = true
82 });
83 return;
84 }
85
86 TryOpen(dir, onError);
87 }
88 catch (Exception ex)
89 {
90 onError?.Invoke(ex.Message);
91 }
92 }
93}
94
95/// <summary>Access to the default OS shell launcher (until full DI is introduced).</summary>
96[IoBoundary]
97public static class OsShell
98{
99 public static IOsShellLauncher Default { get; } = new OsShellLauncher();
100}
101
102
View only · write via MCP/CIDE