@@ -8,7 +8,7 @@ import { HtkConfig } from '../config';
88
99import { getAvailableBrowsers , launchBrowser , BrowserInstance } from '../browsers' ;
1010import { CertCheckServer } from '../cert-check-server' ;
11- import { delay } from '../util' ;
11+ import { delay , windowsKill } from '../util' ;
1212import { Interceptor } from '.' ;
1313import { reportError } from '../error-tracking' ;
1414
@@ -50,7 +50,9 @@ export class FreshFirefox implements Interceptor {
5050 proxyPort ?: number ,
5151 existingPrefs = { }
5252 ) {
53- const browser = await launchBrowser ( certCheckServer . checkCertUrl , {
53+ const initialUrl = certCheckServer . checkCertUrl ;
54+
55+ const browser = await launchBrowser ( initialUrl , {
5456 browser : 'firefox' ,
5557 profile : this . firefoxProfilePath ,
5658 proxy : proxyPort ? `127.0.0.1:${ proxyPort } ` : undefined ,
@@ -120,6 +122,17 @@ export class FreshFirefox implements Interceptor {
120122 if ( browser . process . stdout ) browser . process . stdout . pipe ( process . stdout ) ;
121123 if ( browser . process . stderr ) browser . process . stderr . pipe ( process . stderr ) ;
122124
125+ const normalStop = browser . stop . bind ( browser ) ;
126+ browser . stop = async function ( ) {
127+ if ( process . platform === "win32" ) {
128+ // Firefox spawns a child process on Windows, and doesn't let us kill it at all.
129+ // To fix this, we kill all firefox instances that were started with this exact same URL.
130+ await windowsKill ( `CommandLine Like '%\\\\firefox.exe%${ initialUrl } '` ) ;
131+ } else {
132+ normalStop ( ) ;
133+ }
134+ } ;
135+
123136 return browser ;
124137 }
125138
@@ -160,14 +173,11 @@ export class FreshFirefox implements Interceptor {
160173
161174 let existingPrefs : _ . Dictionary < any > = { } ;
162175
163- if ( await canAccess ( firefoxPrefsFile ) === false && process . platform !== 'win32' ) {
176+ if ( await canAccess ( firefoxPrefsFile ) === false ) {
164177 /*
165178 First time, we do a separate pre-usage startup & stop, without the proxy, for certificate setup.
166179 This helps avoid initial Firefox profile setup request noise, and tidies up some awkward UX where
167180 firefox likes to open extra welcome windows/tabs on first run.
168-
169- Unfortunately, Windows doesn't seem to play nicely with this (because it spawns separate child
170- processes that we can't reliable kill), so we have to fall back to normal behaviour in that case.
171181 */
172182 await this . setupFirefoxProfile ( ) ;
173183 }
@@ -215,8 +225,8 @@ export class FreshFirefox implements Interceptor {
215225 async deactivate ( proxyPort : number | string ) {
216226 if ( this . isActive ( proxyPort ) ) {
217227 const browser = browsers [ proxyPort ] ;
218- const closePromise = new Promise ( ( resolve ) => browser ! . process . once ( 'close' , resolve ) ) ;
219- browser ! . stop ( ) ;
228+ const closePromise = new Promise ( ( resolve ) => browser . process . once ( 'close' , resolve ) ) ;
229+ browser . stop ( ) ;
220230 await closePromise ;
221231 }
222232 }
0 commit comments