Golang - os.StartProcess() 사용 시 오류 정리
살을 붙여 가면서 설명해 보겠습니다. ^^
// 명령행에서 "c:\temp> sc delete test_app"이라고 실행하는 것을 go 언어로 실행
package main
import (
"log"
"os"
)
func main() {
exePath := "sc"
args := []string{"delete", "test_app"}
p, err := os.StartProcess(exePath, args, &os.ProcAttr{})
if err == nil {
status, err := p.Wait()
if err == nil {
log.Printf("errorlevel: %v", status.ExitCode())
}
}
if err != nil {
log.Println(err)
}
}
우선, 위와 같은 식으로 프로그램을 실행하면 이런 오류가 발생합니다.
fork/exec sc: invalid argument
왜냐하면, os.ProcAttr 구조체에는 3개의 표준 I/O, Error 스트림을 지정해야 하기 때문입니다. 그래서 이렇게 지정하면,
var procAttr os.ProcAttr
procAttr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}
exePath := "sc"
args := []string{"delete", "test_app"}
p, err := os.StartProcess(exePath, args, &procAttr)
이제는 이런 오류가 발생합니다.
fork/exec sc: The system cannot find the file specified.
오류 메시지에도 나오지만, 비록 윈도우 명령행에서 어디서든지 실행할 수 있는 sc.exe 실행 파일을 지정했어도 os.StartProcess의 인자에는 정확한 경로를 지정해야 합니다. 따라서 다음과 같이 설정해야 합니다.
exePath := "c:\\windows\\system32\\sc.exe"
// 또는,
// exePath, err := exec.LookPath("sc")
하지만, 그래도 이런 오류가 발생합니다. ^^
ERROR: Unrecognized command
...[생략: sc.exe 실행 결과]...
errorlevel: 1639
실행 결과를 보면, sc.exe 실행 파일 자체는 정상적으로 구동이 된 것을 볼 수 있지만 이제는 명령어에 전달한 옵션이 잘못되었기 때문에 나온 현상입니다. 윈도우 개발자들이 흔히 할 수 있는 실수인데요, *NIX 관행에서는 인자에 실행 파일까지 전달하는 관습(?)이 있어서 옵션에도 다음과 같이 전달해야 합니다.
args := []string{"sc", "delete", "test_app"}
// 또는,
// args := []string{exePath, "delete", "test_app"}
끝입니다. ^^ 저렇게까지 해야 이제 정상적으로 실행됩니다.
그나마 다행인 것은, 전달한 인자에 공백이 있어도 이것을 하나로 인식해 처리해 준다는 점입니다. 그래서 다음과 같이 프로그램 경로와 그 인자에 공백이 있어도,
exePath := "C:\\Program Files\\dotnet\\dotnet.exe"
args := []string{exePath, "C:\\temp\\Console App1\\ConsoleApp1\\bin\\Debug\\net8.0\\ConsoleApp1.dll"}
실행에 문제가 없습니다. ^^
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]