代码之家  ›  专栏  ›  技术社区  ›  Marged

使用lxn/win处理golang的LPTSTR

  •  1
  • Marged  · 技术社区  · 7 年前

    我有一段代码,运行时不返回 err 但由于它没有返回预期的值,所以根本无法完成它的工作。 想法是使用 SHGetSpecialFolderPath 为了检索Windows目录的路径( C:\Windows 例如)。此api调用具有以下签名:

    BOOL SHGetSpecialFolderPath(
            HWND   hwndOwner, 
            _Out_ LPTSTR lpszPath,
            _In_  int    csidl,
            _In_  BOOL   fCreate );
    

    我知道它已被弃用,但即使在当前的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)
    }
    

    没有 犯错误 则API调用返回 true 但字符串不变:

    folder retrieved ok:  true
    folder: XXX...XXX
    

    在Windows 10 x64和运行Windows XP SP3的测试VM上的结果是相同的(我知道XP本身是不安全的)

    我已经看到了如何使用 LPTRSTR 具有 unsafe uintptr 在这里 on SO 和其他网站,但没有一个在我的golang版本上编译 go version go1.10.1 windows/amd64 ,我用编译 GOARCH=386 )

    1 回复  |  直到 7 年前
        1
  •  4
  •   peterSO    7 年前

    以逻辑、系统的方式处理问题。


    请仔细阅读Microsoft文档了解该函数。

    SHGetSpecialFolderPath function


    仔细阅读 lxn/win 函数的软件包文档。

    package win

    import "github.com/lxn/win" 
    

    func SHGetSpecialFolderPath

    func SHGetSpecialFolderPath(hwndOwner HWND, lpszPath *uint16, csidl CSIDL, fCreate bool) bool
    

    现在,使用文档,在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)
    }
    

    输出:

    true
    C:\Windows