Go在windows上调用本地进程传参时的一个天坑
Golang
go在windows上exec.Command调用本地进程在传参的时候有一个天坑,举个栗子来说正常来说一般代码会这么写
cmdLine := "notepad.exe " + `"D:\Program Files\Notepad++\session.xml"`
cmd := exec.Command("cmd.exe", "/c", cmdLine)
err := cmd.Run()
我们期望在拉起notepad的时候是会正常解析参数并打开xml文件的,但是,你可以尝试运行一下这段代码,结果并不是我们想的这样!
notepad在打开的时候会报一个非法路径,这是怎么回事呢?打开processexp看一下传入的参数如下
notepad.exe "D:\Program Files\Notepad++\session.xml"
看到在双引号中强制加入了转义符,一开始我以为这是string里强制加入的,想到这做法也太奇怪了,强制转string为byte[]后,一个一个对字符发现原字符串中根本就没有出现转义符,搜遍国内外只有提问的人,却没找到有效的解决办法。
想了一下,那这问题必然就出在Command解析中了,查看源码中有一段说明
On Windows, processes receive the whole command line as a single string and do their own parsing. Command combines and quotes Args into a command line string with an algorithm compatible with applications using CommandLineToArgvW (which is the most common way). Notable exceptions are msiexec.exe and cmd.exe (and thus, all batch files), which have a different unquoting algorithm. In these or other similar cases, you can do the quoting yourself and provide the full command line in SysProcAttr.CmdLine, leaving Args empty.
也就是说,针对cmd参数加的引号参数会有不同的逻辑,必须在SysProcAttr.CmdLine中写入原始参数了,但是Args留空,又会导致SysProcAttr值为nil,所以简单赋值也是不行的,那么正确的代码实现如下
cmdLine := "notepad.exe " + `"D:\Program Files\Notepad++\session.xml"`
cmd := exec.Command("cmd.exe")
cmd.SysProcAttr = &syscall.SysProcAttr{CmdLine: "/c " + cmdLine}
err := cmd.Run()
运行一下,果然notepad正确打开了文件
原文:https://oser.space/post/gocmd/
标签:exe,SysProcAttr,exec,windows,cmd,notepad,Command,go From: https://www.cnblogs.com/DirWang/p/17443797.html