用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
)
我有这段代码可以运行而不会返回 我知道它已被弃用,但即使在当前Windows版本上仍然可用。 我必须使用此API,因为我需要支持早于Windows 7的Windows版本(我知道这些版本很旧,甚至寿命已尽) p>
这是一段代码: p>
未设置任何 在Windows 10 x64和Windows 10上结果相同 我运行Windows XP SP3的测试VM(我知道XP本质上是不安全的) p>
我已经看到了如何使用 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>
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>
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.
import "github.com/lxn/win"
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