Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open folder in foreground #16

Open
niondir opened this issue Aug 10, 2018 · 6 comments
Open

Open folder in foreground #16

niondir opened this issue Aug 10, 2018 · 6 comments

Comments

@niondir
Copy link

niondir commented Aug 10, 2018

When opening a folder location, the window (at least on windows) appears in background behind other applications. Is there any way to put it in foreground?

@skratchdot
Copy link
Owner

@niondir - in windows, this is the command that is used:
https://github.com/skratchdot/open-golang/blob/master/open/exec_windows.go#L27

Here are the start docs:
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/start

I don't know of a way to force it to open in the foreground. If you find a way that works, you can post the command here, and we could try to submit a PR.

@xiegeo
Copy link

xiegeo commented Aug 10, 2018

You can try SetForegroundWindow if you can get HWND of the window, but windows prevent apps from going into the foreground in some cases, so I couldn't get that to work dependably for me.

The reason that your new window appears in the background is probably of the same reason. If you have a background process that opens a new window without user interaction, at least from how the OS see it, the best it will let you do is flash the taskbar.

I have also tried BringWindowToTop, SwitchToThisWindow, and ShowWindow, but they all seem to have the same limitations.

@niondir
Copy link
Author

niondir commented Aug 11, 2018

Do you know a reliable way of getting the HWND of the just startet process? Or do we need to iterate all handles and find it somehow by name?
I'm really not into window APIs :)

@xiegeo
Copy link

xiegeo commented Aug 11, 2018

@niondir If you know the name, you can use FindWindowW

windowName := "window name"
user32, err = syscall.LoadDLL("user32.dll")
findWindow, err = user32.FindProc("FindWindowW")
hwnd, _, err = findWindow.Call(0, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(windowName))))

@EliCDavis
Copy link

EliCDavis commented Sep 16, 2020

So it seems programs launched by your golang application are only put in the foreground if your golang application itself is in the foreground. So before launching your application, just put your golang application in the foreground first.

Here's what I've done to make a program get launched in the foreground, even though the parent program is in the background initially:

package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"syscall"
	"time"
	"unsafe"
)

var (
	kernel32            = syscall.MustLoadDLL("Kernel32.dll")
	getConsoleWindow    = kernel32.MustFindProc("GetConsoleWindow")
	user32              = syscall.MustLoadDLL("user32.dll")
	setForegroundWindow = user32.MustFindProc("SetForegroundWindow")
)

func getWindowPointer() (syscall.Handle, error) {
	r, _, err := syscall.Syscall(getConsoleWindow.Addr(), 0, 0, 0, 0)
	return syscall.Handle(r), err
}

func bringWindowToForeground(hwnd syscall.Handle) (int, error) {
	sucess, _, err := syscall.Syscall(setForegroundWindow.Addr(), 1, uintptr(hwnd), 0, 0)
	return int(sucess), err
}

func main() {

	winPnt, err := getWindowPointer()
	if err != nil {
		log.Println("errpr", err)
	} 
	fmt.Printf("this windows pointer: %d;\n", int(winPnt))

        // Allows me time to manually click over to another window for sake of example.
	time.Sleep(time.Second * 5)

	success, err := bringWindowToForeground(winPnt)
	if err != nil {
		log.Printf("error bringing to foreground:  %+v\n", err)
	}
	fmt.Printf("success: %d;\n", int(success))

	output, err := exec.Command("my program").Output()
	if err == nil {
		os.Stdout.Write(output)
	} else {
		log.Panicln(err)
	}
}

If you know how to make this fail please let me know! I'm definitely out of my comfort zone with all this, and barely know what I'm doing.

EDIT:
Can confirm this method still works once the application is properly installed on a user's machine (Tested on Windows 10 Pro)

@skratchdot
Copy link
Owner

@EliCDavis - Thank you for sharing what worked for you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants