// launch creates the application process. // It's up to the processmanager to call this function when it makes sense. func (a *Application) launch() { // In windows, `explorer.exe`, in addtion of beeing the file explorer, is // the application responssible of the graphical desktop environment. // In order to decide if `explorer.exe` should be launched as a "simple" // file explorer window or as a full graphical desktop, it firstly checks that // no instances of `explorer.exe` already runs in desktop mode and secondly, // check the value of the shell varible to be nothing else than // `explorer.exe`. // So if the application to be launched is `explorer.exe`, we set the shell // value to `explorer.exe` to get the desktop is needed. if a.Command[0] == `C:\Windows\explorer.exe` { windows.SetWinlogonShell("explorer.exe") } cmd := windows.Command(a.Username, a.Domain, a.HideWindow, a.Command[0], a.Command[1:]...) if a.Stdin != nil { cmd.Stdin = a.Stdin } cmd.Stdout = &a.Stdout cmd.Stderr = &a.Stderr a.cmdChan <- cmd }
// setPid sets the pid of the session. // This occurs when a shell register itself to the processmanager. // Thanks to this, we know that the windows session is up an running. func (s *session) setPid(pid int) error { if s.running { return fmt.Errorf("The session is running already") } proc, err := os.FindProcess(pid) if err != nil { return err } if proc == nil { return fmt.Errorf("Cannot find the specified process. Pid = %d", pid) } s.pid = pid s.running = true go func() { go s.launchApps() proc.Wait() // wait for the session to close. s.running = false // Session stopped. We reset the shell value. windows.SetWinlogonShell("plaza.exe") }() return nil }
// initPlatform should be called when plaza is running as an agent. func initPlatform() { err := windows.SetWinlogonShell("plaza.exe") if err != nil { log.Fatal(err) } }