@@ -23,6 +23,14 @@ public enum PreferredBrowser
2323public class DevToolsPluginConfiguration
2424{
2525 public PreferredBrowser PreferredBrowser { get ; set ; } = PreferredBrowser . Edge ;
26+
27+ /// <summary>
28+ /// Path to the browser executable. If not set, the plugin will try to find
29+ /// the browser executable based on the PreferredBrowser.
30+ /// </summary>
31+ /// <remarks>Use this value when you install the browser in a non-standard
32+ /// path.</remarks>
33+ public string PreferredBrowserPath { get ; set ; } = string . Empty ;
2634}
2735
2836public class DevToolsPlugin : BaseProxyPlugin
@@ -52,47 +60,110 @@ public override void Register()
5260
5361 private static int GetFreePort ( )
5462 {
55- var listener = new TcpListener ( IPAddress . Loopback , 0 ) ;
63+ using var listener = new TcpListener ( IPAddress . Loopback , 0 ) ;
5664 listener . Start ( ) ;
5765 var port = ( ( IPEndPoint ) listener . LocalEndpoint ) . Port ;
5866 listener . Stop ( ) ;
5967 return port ;
6068 }
6169
62- private string GetChromiumProcessName ( DevToolsPluginConfiguration configuration )
70+ private string GetBrowserPath ( DevToolsPluginConfiguration configuration )
6371 {
64- return configuration . PreferredBrowser switch
72+ if ( ! string . IsNullOrEmpty ( configuration . PreferredBrowserPath ) )
6573 {
66- PreferredBrowser . Chrome => RuntimeInformation . IsOSPlatform ( OSPlatform . Windows )
67- ? Environment . ExpandEnvironmentVariables ( @"%ProgramFiles%\Google\Chrome\Application\chrome.exe" )
68- : "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ,
69- PreferredBrowser . EdgeDev => RuntimeInformation . IsOSPlatform ( OSPlatform . Windows )
70- ? Environment . ExpandEnvironmentVariables ( @"%ProgramFiles(x86)%\Microsoft\Edge Dev\Application\msedge.exe" )
71- : "/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev" ,
72- _ => RuntimeInformation . IsOSPlatform ( OSPlatform . Windows )
73- ? Environment . ExpandEnvironmentVariables ( @"%ProgramFiles(x86)%\Microsoft\Edge\Application\msedge.exe" )
74- : "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
75- } ;
74+ Logger . LogInformation ( "{preferredBrowserPath} was set to {path}. Ignoring {preferredBrowser} setting." , nameof ( configuration . PreferredBrowserPath ) , configuration . PreferredBrowserPath , nameof ( configuration . PreferredBrowser ) ) ;
75+ return configuration . PreferredBrowserPath ;
76+ }
77+
78+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
79+ {
80+ return configuration . PreferredBrowser switch
81+ {
82+ PreferredBrowser . Chrome => Environment . ExpandEnvironmentVariables ( @"%ProgramFiles%\Google\Chrome\Application\chrome.exe" ) ,
83+ PreferredBrowser . Edge => Environment . ExpandEnvironmentVariables ( @"%ProgramFiles(x86)%\Microsoft\Edge\Application\msedge.exe" ) ,
84+ PreferredBrowser . EdgeDev => Environment . ExpandEnvironmentVariables ( @"%ProgramFiles(x86)%\Microsoft\Edge Dev\Application\msedge.exe" ) ,
85+ _ => throw new NotSupportedException ( $ "{ configuration . PreferredBrowser } is an unsupported browser. Please change your PreferredBrowser setting for { Name } .")
86+ } ;
87+ }
88+ else if ( RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) )
89+ {
90+ return configuration . PreferredBrowser switch
91+ {
92+ PreferredBrowser . Chrome => "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ,
93+ PreferredBrowser . Edge => "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge" ,
94+ PreferredBrowser . EdgeDev => "/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev" ,
95+ _ => throw new NotSupportedException ( $ "{ configuration . PreferredBrowser } is an unsupported browser. Please change your PreferredBrowser setting for { Name } .")
96+ } ;
97+ }
98+ else if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
99+ {
100+ return configuration . PreferredBrowser switch
101+ {
102+ PreferredBrowser . Chrome => "/opt/google/chrome/chrome" ,
103+ PreferredBrowser . Edge => "/opt/microsoft/msedge-dev/msedge" ,
104+ PreferredBrowser . EdgeDev => "/opt/microsoft/msedge-dev/msedge" ,
105+ _ => throw new NotSupportedException ( $ "{ configuration . PreferredBrowser } is an unsupported browser. Please change your PreferredBrowser setting for { Name } .")
106+ } ;
107+ }
108+ else
109+ {
110+ throw new NotSupportedException ( "Unsupported operating system." ) ;
111+ }
112+ }
113+
114+ private Process [ ] GetBrowserProcesses ( string browserPath )
115+ {
116+ return Process . GetProcesses ( ) . Where ( p =>
117+ p . MainModule is not null && p . MainModule . FileName == browserPath
118+ ) . ToArray ( ) ;
76119 }
77120
78121 private void InitInspector ( )
79122 {
123+ var browserPath = string . Empty ;
124+
125+ try
126+ {
127+ browserPath = GetBrowserPath ( _configuration ) ;
128+ }
129+ catch ( NotSupportedException ex )
130+ {
131+ Logger . LogError ( ex , "Error starting {plugin}. Error finding the browser." , Name ) ;
132+ return ;
133+ }
134+
135+ // check if the browser is installed
136+ if ( ! File . Exists ( browserPath ) )
137+ {
138+ Logger . LogError ( "Error starting {plugin}. Browser executable not found at {browserPath}" , Name , browserPath ) ;
139+ return ;
140+ }
141+
142+ // find if the process is already running
143+ var processes = GetBrowserProcesses ( browserPath ) ;
144+
145+ if ( processes . Any ( ) )
146+ {
147+ var ids = string . Join ( ", " , processes . Select ( p => p . Id . ToString ( ) ) ) ;
148+ Logger . LogError ( "Found existing browser process {processName} with IDs {processIds}. Could not start {plugin}. Please close existing browser processes and restart Dev Proxy" , browserPath , ids , Name ) ;
149+ return ;
150+ }
151+
80152 var port = GetFreePort ( ) ;
81153 webSocket = new WebSocketServer ( port , Logger ) ;
82154 webSocket . MessageReceived += SocketMessageReceived ;
83155 webSocket . Start ( ) ;
84156
85- var processName = GetChromiumProcessName ( _configuration ) ;
86157 var inspectionUrl = $ "http://localhost:9222/devtools/inspector.html?ws=localhost:{ port } ";
87158 var args = $ "{ inspectionUrl } --remote-debugging-port=9222 --profile-directory=devproxy";
88159
89- Logger . LogInformation ( "DevTools available at {inspectionUrl}" , inspectionUrl ) ;
160+ Logger . LogInformation ( "{name} available at {inspectionUrl}" , Name , inspectionUrl ) ;
90161
91162 var process = new Process
92163 {
93164 StartInfo = new ( )
94165 {
95- FileName = processName ,
166+ FileName = browserPath ,
96167 Arguments = args ,
97168 // suppress default output
98169 RedirectStandardError = true ,
0 commit comments