0

I'm trying to call appcmd from within Go. The code below shows success, but the password is set to the wrong thing. If I remove the inner quotes (on the second line of main) it works, but then it doesn't work when the password includes spaces! Now WITH the quotes, if I type in cmd.exe the command exactly as it outputs, it works! So what the heck! Why does it work with the quotes directly in cmd but not when called from Go?

I really don't want to be that guy who says you can't use spaces in passwords because I can't figure out why it doesn't work! UGH!

package main

import (
    "bytes"
    "fmt"
    "os/exec"
    "strconv"
    "strings"
    "syscall"
)

func main() {
    iisPath := "C:\\WINDOWS\\sysWOW64\\inetsrv\\"
    callAppcmd(iisPath, "-processModel.password:\"password\"")
}

func callAppcmd(iisPath string, param string) {
    stdOut, _, _, exitCode := runCommand(
        iisPath+"appcmd.exe",
        "set",
        "apppool",
        "/apppool.name:DefaultAppPool",
        param)

    printOut(stdOut)
    printOut(strconv.Itoa(exitCode))
}

func printOut(text string) {
    fmt.Println(text)
}

func runCommand(commands ...string) (string, string, error, int) {
    printOut(strings.Join(commands, " "))
    cmd := exec.Command(commands[0], commands[1:]...)
    cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
    var out bytes.Buffer
    var stderr bytes.Buffer
    cmd.Stdout = &out
    cmd.Stderr = &stderr
    err := cmd.Run()

    exitCode := 0

    if exitError, ok := err.(*exec.ExitError); ok {
        exitCode = exitError.ExitCode()
    }

    return out.String(), stderr.String(), err, exitCode
}

Output:

C:\WINDOWS\sysWOW64\inetsrv\appcmd.exe set apppool /apppool.name:DefaultAppPool -processModel.password:"password"
APPPOOL object "DefaultAppPool" changed

0
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Andrew
  • 1,571
  • 17
  • 31

1 Answers1

1

It seems to format the string with backticks is a solution to this, which will not do automatic escaping and can process the quotes properly.

cmd := exec.Command(`find`)
cmd.SysProcAttr.CmdLine = `find "SomeText" test.txt`

Please refer to the below link.
exec with double quoted argument

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22
  • Thank you! It's actually the use of cmd.SysProcAttr.CmdLine instead of just shoving it all into Command() that makes the difference for me. If you can update your answer to hint at that, I'll accept it as the answer. – Andrew Aug 07 '20 at 19:00
  • Sorry, I am not familiar with Go. Thanks for your suggestions. I updated it. Also, help me improve it if you would like. – Abraham Qian Aug 11 '20 at 10:58