swiftlang/swift-corelibs-foundation

on windows, `Process.terminate` doesn't work

Closed this issue · 1 comments

i've noticed that process.terminate doesn't work. sometimes it fails saying i don't have permission, other times it just silently fails and leaves the app running.

repro steps:

  1. Add this following code to a new swift application:
let process = Process()
process.executableURL = URL(fileURLWithPath: "C://windows//system32//notepad.exe")

try! process.run()

Thread.sleep(forTimeInterval: 3)

process.terminate()
print("done")
  1. swift run the app

Expected

You see notepad launch for 3 seconds, then close.

Actual

Notepad stays open

This is working as intended, the problem is Windows.

notepad.exe is now a "modern" application, which means that there is a COM server in between. The process that is launched launches another process and thus the connection between the two is lost.

A simple way to observe this would be to print process.processIdentifier on the process and correlate that to what you see in task manager.

import Foundation

let process: Process = Process()
process.executableURL = URL(fileURLWithPath: #"C:\Windows\system32\notepad.exe"#)
do {
  try process.run()
  Thread.sleep(forTimeInterval: 3)
  print(process.processIdentifier)
  process.terminate()
} catch {
  print(error)
}

You can replace notepad with a small test executable e.g.

import Foundation
import WinSDK

_ = "Hello World".withCString(encodedAs: UTF16.self) {
    MessageBoxW(nil, $0, $0, UINT(MB_OK))
}

Running that will properly get handled.