调用Windows函数(获取字体目录)

huangapple go评论102阅读模式
英文:

Call windows function (getting the font directory)

问题

我试图找出Windows安装中的字体文件夹。据我所知,建议的方法是调用Shell32.dll中的SHGetKnownFolderPath,并将KNOWNFOLDERID设置为FOLDERID_Fonts

我不知道在下面的代码中应该传递给Call函数的内容:

package main

import (
	"syscall"
)

func main() {
	// HRESULT SHGetKnownFolderPath(
	//   _In_      REFKNOWNFOLDERID rfid,
	//   _In_      DWORD dwFlags,
	//   _In_opt_  HANDLE hToken,
	//   _Out_     PWSTR *ppszPath
	// );

	var (
		shell32             = syscall.NewLazyDLL("Shell32.dll")
		shGetKnowFolderPath = shell32.NewProc("SHGetKnownFolderPath")

		// 当然不起作用:
		folderId int
		flags    int
		handle   int
		retval   int
	)

	shGetKnowFolderPath.Call(uintptr(folderId), uintptr(flags), uintptr(handle), uintptr(retval))
}

有什么想法吗?(我猜现在的解决方法是使用%windir%\Fonts,但我想得到一个正确的解决方案)。

参考资料:

英文:

I try to find out the font folder on a windows installation. AFAICS the proposed way is to call SHGetKnownFolderPath in Shell32.dll with KNOWNFOLDERID set to FOLDERID_Fonts.

I have no idea what to pass to the Call function in the code below:

package main

import (
	"syscall"
)

func main() {
	// HRESULT SHGetKnownFolderPath(
	//   _In_      REFKNOWNFOLDERID rfid,
	//   _In_      DWORD dwFlags,
	//   _In_opt_  HANDLE hToken,
	//   _Out_     PWSTR *ppszPath
	// );

	var (
		shell32             = syscall.NewLazyDLL("Shell32.dll")
		shGetKnowFolderPath = shell32.NewProc("SHGetKnownFolderPath")

		// Doesn't work, of course:
		folderId int
		flags    int
		handle   int
		retval   int
	)

	shGetKnowFolderPath.Call(uintptr(folderId), uintptr(flags), uintptr(handle), uintptr(retval))
}

Any idea? (I guess a workaround for now would be to stick to %windir%\Fonts, but I'd like to get a proper solution).

References:

答案1

得分: 10

例如,

package main

import (
	"fmt"
	"syscall"
	"unsafe"
)

type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

var (
	FOLDERID_Fonts = GUID{0xFD228CB7, 0xAE11, 0x4AE3, [8]byte{0x86, 0x4C, 0x16, 0xF3, 0x91, 0x0A, 0xB8, 0xFE}}
)

var (
	modShell32               = syscall.NewLazyDLL("Shell32.dll")
	modOle32                 = syscall.NewLazyDLL("Ole32.dll")
	procSHGetKnownFolderPath = modShell32.NewProc("SHGetKnownFolderPath")
	procCoTaskMemFree        = modOle32.NewProc("CoTaskMemFree")
)

func SHGetKnownFolderPath(rfid *GUID, dwFlags uint32, hToken syscall.Handle, pszPath *uintptr) (retval error) {
	r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(rfid)), uintptr(dwFlags), uintptr(hToken), uintptr(unsafe.Pointer(pszPath)), 0, 0)
	if r0 != 0 {
		retval = syscall.Errno(r0)
	}
	return
}

func CoTaskMemFree(pv uintptr) {
	syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(pv), 0, 0)
	return
}

func FontFolder() (string, error) {
	var path uintptr
	err := SHGetKnownFolderPath(&FOLDERID_Fonts, 0, 0, &path)
	if err != nil {
		return "", err
	}
	defer CoTaskMemFree(path)
	folder := syscall.UTF16ToString((*[1 << 16]uint16)(unsafe.Pointer(path))[:])
	return folder, nil
}

func main() {
	folder, err := FontFolder()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("Font Folder:", folder)
}

输出:

Font Folder: C:\Windows\Fonts
英文:

For example,

package main

import (
	&quot;fmt&quot;
	&quot;syscall&quot;
	&quot;unsafe&quot;
)

type GUID struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

var (
	FOLDERID_Fonts = GUID{0xFD228CB7, 0xAE11, 0x4AE3, [8]byte{0x86, 0x4C, 0x16, 0xF3, 0x91, 0x0A, 0xB8, 0xFE}}
)

var (
	modShell32               = syscall.NewLazyDLL(&quot;Shell32.dll&quot;)
	modOle32                 = syscall.NewLazyDLL(&quot;Ole32.dll&quot;)
	procSHGetKnownFolderPath = modShell32.NewProc(&quot;SHGetKnownFolderPath&quot;)
	procCoTaskMemFree        = modOle32.NewProc(&quot;CoTaskMemFree&quot;)
)

func SHGetKnownFolderPath(rfid *GUID, dwFlags uint32, hToken syscall.Handle, pszPath *uintptr) (retval error) {
	r0, _, _ := syscall.Syscall6(procSHGetKnownFolderPath.Addr(), 4, uintptr(unsafe.Pointer(rfid)), uintptr(dwFlags), uintptr(hToken), uintptr(unsafe.Pointer(pszPath)), 0, 0)
	if r0 != 0 {
		retval = syscall.Errno(r0)
	}
	return
}

func CoTaskMemFree(pv uintptr) {
	syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(pv), 0, 0)
	return
}

func FontFolder() (string, error) {
	var path uintptr
	err := SHGetKnownFolderPath(&amp;FOLDERID_Fonts, 0, 0, &amp;path)
	if err != nil {
		return &quot;&quot;, err
	}
	defer CoTaskMemFree(path)
	folder := syscall.UTF16ToString((*[1 &lt;&lt; 16]uint16)(unsafe.Pointer(path))[:])
	return folder, nil
}

func main() {
	folder, err := FontFolder()
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(&quot;Font Folder:&quot;, folder)
}

Output:

Font Folder: C:\Windows\Fonts

答案2

得分: 5

golang.org/x/sys/windows现在有一个SHGetKnownFolderPath的包装器,所以这变得更容易了:

package main

import (
	"fmt"

	"golang.org/x/sys/windows"
)

func main() {
	path, err := windows.KnownFolderPath(windows.FOLDERID_Fonts, 0)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(path)
}
英文:

golang.org/x/sys/windows now has a wrapper for SHGetKnownFolderPath, so this is much easier:

package main

import (
	&quot;fmt&quot;

	&quot;golang.org/x/sys/windows&quot;
)

func main() {
	path, err := windows.KnownFolderPath(windows.FOLDERID_Fonts, 0)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(path)
}

答案3

得分: 2

只是以防万一有人需要以golang格式获取文档文件夹的文件夹ID:

请在peterSO的代码示例中替换以下内容:

FOLDERID_Documents = GUID{0xFDD39AD0, 0x238F, 0x46AF, [8]byte{0xAD, 0xB4, 0x6C, 0x85, 0x48, 0x03, 0x69, 0xC7}}

FOLDERID_PublicDocuments = GUID{0xED4824AF, 0xDCE4, 0x45A8, [8]byte{0x81, 0xE2, 0xFC, 0x79, 0x65, 0x08, 0x36, 0x34}}

参见:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx

英文:

Just in case someone needs the folder id for documents in golang format:

Replace this in peterSO's code example:

FOLDERID_Documents = GUID{0xFDD39AD0, 0x238F, 0x46AF, [8]byte{0xAD, 0xB4, 0x6C, 0x85, 0x48, 0x03, 0x69, 0xC7}}

FOLDERID_PublicDocuments = GUID{0xED4824AF, 0xDCE4, 0x45A8, [8]byte{0x81, 0xE2, 0xFC, 0x79, 0x65, 0x08, 0x36, 0x34}}

see

https://msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx

答案4

得分: -1

fonts目录的folderId{FD228CB7-AE11-4AE3-864C-16F3910AB8FE}

flags可能是SHGFP_TYPE_DEFAULT

handle可能是NULL

retval 我认为 应该是一个bool类型,但我不确定。

所有答案都来自你之前提供的SHGetFolderPath函数

英文:

folderId for the fonts directory is {FD228CB7-AE11-4AE3-864C-16F3910AB8FE}

flags can probably be SHGFP_TYPE_DEFAULT

handle can probably be NULL

retval I think should be a bool but I'm not sure.

All answers are from your previously linked SHGetFolderPath function.

huangapple
  • 本文由 发表于 2013年7月30日 19:50:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/17946269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定