Getting the default browser runnning on a windows system

60 Views Asked by At

I am trying to write code to return the path to the default browser on windows system.

I have run this command in the temrinal :

for /f "tokens=3" %a in ('reg QUERY HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html\UserChoice /v ProgId') do reg QUERY HKCR\%a\shell\open\command

and got:

(Default) REG_SZ "C:\Program Files\Google\Chrome\Application\chrome.exe" --single-argument %1

Then I tried to use this in the Go code like that :

func main() {
   var c *exec.Cmd


   c = exec.Command("cmd", "for /f \"tokens=3\" %a in ('reg QUERY   HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.html\\UserChoice /v       ProgId') do reg QUERY HKCR\\%a\\shell\\open\\command")


   if output, err := c.CombinedOutput(); err != nil {
      fmt.Println("Error: ", err)
   } else {
      fmt.Println(string(output))
   }`your text`
}

but instead I got :

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

How can i get get same answer of terminal using Go?

1

There are 1 best solutions below

0
kostix On

You could call a bunch of Win32 API functions provided by the standard syscall package.

A demo program which queries the (string) value of HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Desktop:

package main

import (
    "fmt"
    "log"
    "syscall"
    "unsafe"
)

func openKey(keyName string) (handle syscall.Handle, err error) {
    keyNameU16 := syscall.StringToUTF16(keyName)

    err = syscall.RegOpenKeyEx(syscall.HKEY_CURRENT_USER,
        &keyNameU16[0], 0, syscall.KEY_QUERY_VALUE, &handle)

    return
}

func readStringValue(hKey syscall.Handle, valueName string) (string, error) {
    valNameU16 := syscall.StringToUTF16(valueName)

    const defaultBufLen = 256

    valueU16 := make([]uint16, defaultBufLen)
    valueLen := uint32(len(valueU16) * 2)

    for {
        err := syscall.RegQueryValueEx(hKey, &valNameU16[0], nil, nil,
            (*byte)(unsafe.Pointer(&valueU16[0])), &valueLen)

        if err == nil {
            break
        }

        if err != syscall.ERROR_MORE_DATA {
            return "", err
        }

        if valueLen%2 != 0 || int(valueLen/2) < len(valueU16) {
            return "", fmt.Errorf("invalid output value length: %d", valueLen)
        }

        valueU16 = make([]uint16, valueLen/2)
        continue
    }

    return syscall.UTF16ToString(valueU16[:valueLen/2]), nil
}

func main() {
    log.SetFlags(0)

    hKey, err := openKey(`SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders`)
    if err != nil {
        log.Fatal(err)
    }
    defer syscall.RegCloseKey(hKey)

    s, err := readStringValue(hKey, `Desktop`)
    if err != nil {
        log.Fatal(err)
    }

    log.Println(s)
}

I do not have the keys you're interested in on my system, so I tested whatever I have. It's trivial to adapt this to your needs.

You can start by reading the docs on RegQueryValueEx.