@@ -306,6 +306,9 @@ describe("restart-helper", () => {
306306 expect ( vbsPath ) . toBe ( "C:\\Temp\\fake-script.vbs" ) ;
307307 expect ( vbsContent ) . toContain ( "WScript.Shell" ) ;
308308 expect ( vbsContent ) . toContain ( "cmd.exe" ) ;
309+ // VBScript should NOT double backslashes (VBS treats \ literally)
310+ expect ( vbsContent ) . toContain ( "C:\\Temp\\fake-script.bat" ) ;
311+ expect ( vbsContent ) . not . toContain ( "C:\\\\Temp" ) ;
309312
310313 // Should spawn wscript.exe with the VBS wrapper
311314 expect ( spawn ) . toHaveBeenCalledWith ( "wscript.exe" , [ vbsPath ] , {
@@ -316,5 +319,40 @@ describe("restart-helper", () => {
316319 expect ( mockChild . unref ) . toHaveBeenCalled ( ) ;
317320 writeFileSpy . mockRestore ( ) ;
318321 } ) ;
322+
323+ it ( "handles paths with spaces and special characters on Windows" , async ( ) => {
324+ Object . defineProperty ( process , "platform" , { value : "win32" } ) ;
325+ const scriptPath = "C:\\Users\\My User\\AppData\\Local\\Temp\\openclaw-restart-123.bat" ;
326+ const mockChild = { unref : vi . fn ( ) } ;
327+ vi . mocked ( spawn ) . mockReturnValue ( mockChild as unknown as ChildProcess ) ;
328+ const writeFileSpy = vi . spyOn ( fs , "writeFile" ) . mockResolvedValueOnce ( undefined ) ;
329+
330+ await runRestartScript ( scriptPath ) ;
331+
332+ const [ , vbsContent ] = writeFileSpy . mock . calls [ 0 ] as [ string , string , string ] ;
333+ // Path with spaces should be preserved as-is (no backslash doubling)
334+ expect ( vbsContent ) . toContain ( "C:\\Users\\My User\\AppData" ) ;
335+ expect ( vbsContent ) . not . toContain ( "\\\\" ) ;
336+ writeFileSpy . mockRestore ( ) ;
337+ } ) ;
338+
339+ it ( "falls back to cmd.exe when VBS file write fails on Windows" , async ( ) => {
340+ Object . defineProperty ( process , "platform" , { value : "win32" } ) ;
341+ const scriptPath = "C:\\Temp\\fake-script.bat" ;
342+ const mockChild = { unref : vi . fn ( ) } ;
343+ vi . mocked ( spawn ) . mockReturnValue ( mockChild as unknown as ChildProcess ) ;
344+ const writeFileSpy = vi . spyOn ( fs , "writeFile" ) . mockRejectedValueOnce ( new Error ( "disk full" ) ) ;
345+
346+ await runRestartScript ( scriptPath ) ;
347+
348+ // Should fall back to direct cmd.exe spawn
349+ expect ( spawn ) . toHaveBeenCalledWith ( "cmd.exe" , [ "/d" , "/s" , "/c" , scriptPath ] , {
350+ detached : true ,
351+ stdio : "ignore" ,
352+ windowsHide : true ,
353+ } ) ;
354+ expect ( mockChild . unref ) . toHaveBeenCalled ( ) ;
355+ writeFileSpy . mockRestore ( ) ;
356+ } ) ;
319357 } ) ;
320358} ) ;
0 commit comments