我有这段代码运行时不返回err,但根本没有完成其工作,因为它没有返回预期值。这个想法是SHGetSpecialFolderPath为了检索 Windows 目录的路径(C:\Windows例如)。此 api 调用具有以下签名:
BOOL SHGetSpecialFolderPath(
HWND hwndOwner,
_Out_ LPTSTR lpszPath,
_In_ int csidl,
_In_ BOOL fCreate );
Run Code Online (Sandbox Code Playgroud)
我知道它已被弃用,但即使在当前的 Windows 版本上仍然可用。我必须使用这个 API,因为我需要支持早于 Windows 7 的 Windows 版本(我知道这些版本已经过时,甚至已经停产)
这是一段代码:
target := "XXX...XXX" // hard coded string with more than 600 characters
buffer, err := syscall.UTF16PtrFromString(target)
if err != nil {
fmt.Println("conversion of string:", err)
}
result := win.SHGetSpecialFolderPath(0, buffer, win.CSIDL_WINDOWS, false)
if err != nil {
fmt.Println("result of get folder:", err)
}
fmt.Println("folder retrieved ok: ", result)
fmt.Println("folder: ", target)
}
Run Code Online (Sandbox Code Playgroud)
均未设置err,API 调用返回true,但字符串未更改:
folder retrieved ok: true
folder: XXX...XXX
Run Code Online (Sandbox Code Playgroud)
结果在 Windows 10 x64 和运行 Windows XP SP3 的测试虚拟机上是相同的(我知道 XP 本质上是不安全的)
我已经在 SO和其他网站上看到了如何使用LPTRSTRwithunsafe和uintptrhere 的示例,但它们都没有在我的 golang 版本上编译(即,我用 编译)go version go1.10.1 windows/amd64GOARCH=386
以逻辑、系统的方式解决问题。
仔细阅读该函数的 Microsoft 文档。
仔细阅读lxn/win该函数的包文档。
import "github.com/lxn/win"
Run Code Online (Sandbox Code Playgroud)
func SHGetSpecialFolderPath(hwndOwner HWND, lpszPath *uint16, csidl CSIDL, fCreate bool) bool
Run Code Online (Sandbox Code Playgroud)
现在,使用文档,在 Go 中实现函数调用。Go Unicode 字符串是 UTF-8 编码的。Windows Unicode 字符串采用 UTF-16 编码。
package main
import (
"fmt"
"syscall"
"github.com/lxn/win"
)
func main() {
buf := make([]uint16, win.MAX_PATH)
rv := win.SHGetSpecialFolderPath(win.HWND(0), &buf[0], win.CSIDL_WINDOWS, false)
fmt.Println(rv)
path := syscall.UTF16ToString(buf)
fmt.Println(path)
}
Run Code Online (Sandbox Code Playgroud)
输出:
true
C:\Windows
Run Code Online (Sandbox Code Playgroud)