github.com/btwiuse/jiri@v0.0.0-20191125065820-53353bcfef54/osutil/exec_windows.go (about)

     1  // Copyright 2016 The Fuchsia Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build windows
     6  
     7  package osutil
     8  
     9  import (
    10  	"path/filepath"
    11  	"syscall"
    12  	"unsafe"
    13  )
    14  
    15  var (
    16  	kernel32               = syscall.MustLoadDLL("kernel32.dll")
    17  	procGetModuleFileNameW = kernel32.MustFindProc("GetModuleFileNameW")
    18  )
    19  
    20  // Executable returns an absolute path to the currently executing program.
    21  func getModuleFileName(handle syscall.Handle) (string, error) {
    22  	n := uint32(1024)
    23  	var buf []uint16
    24  	for {
    25  		buf = make([]uint16, n)
    26  		r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(0), uintptr(unsafe.Pointer(&buf[0])), uintptr(n))
    27  		r := uint32(r0)
    28  		if r == 0 {
    29  			if e1 != 0 {
    30  				return "", error(e1)
    31  			} else {
    32  				return "", syscall.EINVAL
    33  			}
    34  		}
    35  		if r < n {
    36  			break
    37  		}
    38  		n += 1024
    39  	}
    40  	return syscall.UTF16ToString(buf), nil
    41  }
    42  
    43  func Executable() (string, error) {
    44  	p, err := getModuleFileName(0)
    45  	return filepath.Clean(p), err
    46  }