用lxn / win处理golang中的LPTSTR

用lxn / win处理golang中的LPTSTR

问题描述:

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)

我有这段代码可以运行而不会返回 err code>,但是根本不执行 它的工作是因为它没有返回期望的值。 想法是使用 SHGetSpecialFolderPath code> 以便检索Windows目录的路径(例如, C:\ Windows code>)。 此api调用具有以下签名: p>

  BOOL SHGetSpecialFolderPath(
 HWND hwndOwner,
 _Out_ LPTSTR lpszPath,
 _In_ int csidl,
 _In_ BOOL fCreate); \  n  code>  pre> 
 
 

我知道它已被弃用,但即使在当前Windows版本上仍然可用。 我必须使用此API,因为我需要支持早于Windows 7的Windows版本(我知道这些版本很旧,甚至寿命已尽) p>

这是一段代码: p>

  target:=“ XXX ... XXX” //超过600个字符的硬编码字符串
buffer,err:= syscall.UTF16PtrFromString(target)
if err!= nil  {
 fmt.Println(“字符串转换:”,错误)
} 
 
result:= win.SHGetSpecialFolderPath(0,buffer,win.CSIDL_WINDOWS,false)
if err!= nil {
 fmt。  Println(“获取文件夹的结果:”,错误)
} 
 
fmt.Println(“文件夹检索成功:”,结果)
fmt.Println(“文件夹:”,目标)
} 
   code>  pre> 
 
 

未设置任何 err code>,API调用返回 true code>,但字符串未更改: p> \ n

 文件夹检索成功:true 
文件夹:XXX ... XXX 
  code>  pre> 
 
 

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

我已经看到了如何使用 LPTRS的示例 TR code>和 unsafe code>和 uintptr code>在这里在SO 和其他网站上,但没有一个在我的golang版本(即 go version go1.10.1 windows / amd64 code>,我使用 GOARCH = 386 ) p> div>

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