Created
May 3, 2016 18:42
-
-
Save mitchellh/4b98bccc9b6d229ebbd95f120f4e0217 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Package winfolder returns the path to known folders on Windows. | |
// This package will only build on Windows, so make sure that any | |
// Go file using it is guarded to only build on Windows. | |
package winfolder | |
import ( | |
"fmt" | |
"syscall" | |
"unsafe" | |
) | |
var ( | |
modShell32 = syscall.NewLazyDLL("Shell32.dll") | |
procSHGetKnownFolderPath = modShell32.NewProc("SHGetKnownFolderPath") | |
modOle32 = syscall.NewLazyDLL("Ole32.dll") | |
procCoTaskMemFree = modOle32.NewProc("CoTaskMemFree") | |
// {F1B32785-6FBA-4FCF-9D55-7B8E7F157091} | |
FOLDERID_LocalAppData = syscall.GUID{0xF1B32785, 0x6FBA, 0x4FCF, [8]byte{0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91}} | |
) | |
// Path returns the path to a known folder for Windows. | |
// | |
// The folderId argument should be the GUID for the known folder path. Many | |
// are provided as constants to this package. | |
func Path(folderId syscall.GUID) (string, error) { | |
// Get the path to local app data folder | |
var raw *uint16 | |
ret, _, err := procSHGetKnownFolderPath.Call( | |
uintptr(unsafe.Pointer(&folderId)), | |
0, | |
0, | |
uintptr(unsafe.Pointer(&raw))) | |
if ret != 0 { | |
return "", fmt.Errorf("Failed to read folder: %s", err) | |
} | |
// Defer freeing memory since this API call is managed | |
defer procCoTaskMemFree.Call(uintptr(unsafe.Pointer(raw))) | |
// Convert UTF-16 to a Go string | |
return syscall.UTF16ToString((*[1 << 16]uint16)(unsafe.Pointer(raw))[:]), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment