7

I'd like to open a PDF file in the filesystem from go with the default application. How can I do that? From the command line I just write the filename of the pdf file and the application opens (with the requested file). When I try to use exec.Command() I get an error (not surprisingly) exec: "foo.pdf": executable file not found in %PATH%.

package main

import (
    "log"
    "os/exec"
)

func main() {
    cmd := exec.Command("foo.pdf")
    err := cmd.Start()
    if err != nil {
        log.Fatal(err)
    }
    err = cmd.Wait()
    if err != nil {
        log.Fatal(err)
    }

}
topskip
  • 16,207
  • 15
  • 67
  • 99

3 Answers3

13
exec.Command("rundll32.exe", "url.dll,FileProtocolHandler", "path_to_foo.pdf")

should also handle it.

Note that still the right way to do it is to use a C wrapper around the ShellExecute() API function exported by shell32.dll, and the "w32" library seems to provide this wrapper right away.

kostix
  • 51,517
  • 14
  • 93
  • 176
3

You must launch cmd /C start foo.pdf. This will let the start command find the correct executable for you.

cmd := exec.Command("cmd", "/C start path_to_foo.pdf")
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • I think opening a filename with spaces in it should be possible. See http://stackoverflow.com/a/13692919/395461 But I couldn't get the command to work properly in Go, even though it would when entered manually on the command line. – Shannon Matthews Jul 02 '15 at 06:45
  • Is there a cross platform way to do this? – mikedoy Apr 08 '20 at 18:31
0

Create a file like this:

//go:generate mkwinsyscall -output zmain.go main.go
//sys shellExecute(hwnd int, oper string, file string, param string, dir string, show int) (err error) = shell32.ShellExecuteW
package main

const sw_shownormal = 1

func main() {
   shellExecute(0, "", "file.pdf", "", "", sw_shownormal)
}

Then build:

go mod init pdf
go generate
go mod tidy
go build

https://pkg.go.dev/golang.org/x/sys/windows/mkwinsyscall

Zombo
  • 1
  • 62
  • 391
  • 407