How can i execute sc create command through exec os/exec?

964 Views Asked by At

How can i execute my sc command through exec.Command?

Code:

cmd := exec.Command("cmd.exe", "sc", "create", "Simpler", "binpath="+os.Getenv("APPDATA")+"\\Simpler\\cc.exe", "displayname=MY SERVICE");
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true};
out, _ := cmd.Output(); fmt.Println(string(out))

This i get in command prompt (open command prompt in current command prompt -_-):

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>cd c:\prog\logs

c:\prog\logs>go build test.go

c:\prog\logs>test.exe
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

c:\prog\logs>

c:\prog\logs>

Followed command cannot be executed. I do not get anything! Where is the problem?

Command been started if i execute sc.exe in current command prompt but not started if i execute in new command prompt.

That is if i remove first argument "cmd.exe" my program succesfully execute with excepted result. But how to execute in a new window?

3

There are 3 best solutions below

1
kostix On BEST ANSWER

Well, the immediate problem is that what you do is not how cmd.exe should be told to execute an external command—in order to make it execute one, you should pass cmd.exe either the /C or /K command-line option, like in

C:\>cmd.exe /C sc whatever sc_arg1 sc_arg2 ...

What you observe with your call is that cmd.exe ignores the rest of the arguments you pass to it and just runs—that's exactly what you're observing.

Start with studying the output of cmd.exe /? and the built-in Windows help system to get better idea of how it works.

The next problem is that there is absolutely no reason to make cmd.exe involved in running sc—just run sc directly rather than jumping around cmd.exe to make it execute sc.

The next problem is that you're ignoring the error value returned by the call to os/exec.Cmd.Output. Since Go (luckily) does not have exceptions, handing all error values is of paramount importance—it's better to ignore everything else but not errors. If you're writing highly-experimental code, you might start with a dumb helper like

func check(err error) {
    if err != nil {
        panic(err)
    }
}

and then roll like

out, err := cmd.Output()
check(err)

This approach is not for production-grade code, but allows for faster code churn when experimenting.

You might also consider calling directly into Win32 API to manage services as it will make error handling substantially easier.

0
leaf bebop On

A little bit late and not really about running sc.exe. While the problem of using SC.exe is solved in the answer @kostix provides, I see that you are trying to create a service of a Go application and consider this an XY problem.

It is not likely that a single call of sc.exe would successfully create a windows service. However, there is a lib to help: golang.org/x/sys/windows/svc.

There is also an example on github: https://github.com/golang/sys/tree/master/windows/svc/example

0
Ritu Gupta On

CODE:

   func main() {
        data, _ := exec.Command("cmd.exe", "/C", "sc", "qc", "serviceName").Output()
        fmt.Println(string(data))
  }

OUTPUT:

[SC] QueryServiceConfig SUCCESS                                                                         
                                                                                                        
SERVICE_NAME: serviceName                                                                                  
        TYPE               : 10  WIN32_OWN_PROCESS                                                      
        START_TYPE         : 2   AUTO_START                                                             
        ERROR_CONTROL      : 1   NORMAL                                                                 
        BINARY_PATH_NAME   : "C:\Program Files\serviceName
        LOAD_ORDER_GROUP   :                                                                            
        TAG                : 0                                                                          
        DISPLAY_NAME       : Display Server                                                           
        DEPENDENCIES       : Tcpip                                                                      
                           : Afd                                                                        
        SERVICE_START_NAME : LocalSystem