Handling LPTSTR in golang with lxn/win

不打扰是莪最后的温柔 提交于 2021-02-19 23:57:32

问题


I have this piece of code which runs without returning err but simply doesn't do its job because it doesn't return the expected value. The idea is to use SHGetSpecialFolderPath in order to retrieve the path to the Windows directory (C:\Windows for example). This api call has the following signature:

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

I know it is deprecated, but still available even on current Windows versions. I have to use this API because I need to support Windows versions older than Windows 7 (I know that these are old or even end of life)

This is the piece of code:

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)
}

None of the err is set, the API call returns true but the string is unchanged:

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

The result is the same on Windows 10 x64 and on my testing VM running Windows XP SP3 (I know that XP is inherently unsafe)

I have seen examples how to use LPTRSTR with unsafe and uintptr here on SO and other sites but none of them compile on my version of golang (which is go version go1.10.1 windows/amd64, I compiled with GOARCH=386)


回答1:


Approach the problem in a logical, systematic fashion.


Carefully read the Microsoft documentation for the function.

SHGetSpecialFolderPath function


Carefully read the lxn/win package documentation for the function.

package win

import "github.com/lxn/win" 

func SHGetSpecialFolderPath

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

Now, using the documentation, implement the function call in Go. Go Unicode strings are UTF-8 encoded. Windows Unicode strings are UTF-16 encoded.

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)
}

Output:

true
C:\Windows


来源:https://stackoverflow.com/questions/49910002/handling-lptstr-in-golang-with-lxn-win

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!