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

Winapi 调用windows函数(获取字体目录),winapi,go,Winapi,Go,我尝试查找windows安装中的字体文件夹。AFAICS建议的方法是在Shell32.dll中调用SHGetKnownFolderPath,并将KNOWNFOLDERID设置为FOLDERID\u Fonts 我不知道如何传递到下面代码中的调用函数: package main import ( "syscall" ) func main() { // HRESULT SHGetKnownFolderPath( // _In_ REFKNOWNFOLDER

我尝试查找windows安装中的字体文件夹。AFAICS建议的方法是在
Shell32.dll
中调用
SHGetKnownFolderPath
,并将
KNOWNFOLDERID
设置为
FOLDERID\u Fonts

我不知道如何传递到下面代码中的
调用
函数:

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))
}
有什么想法吗?(我想现在的解决办法是坚持使用
%windir%\font
,但我想得到一个合适的解决方案)

参考资料:


  • 字体目录的folderId是
    {FD228CB7-AE11-4AE3-864C-16F3910AB8FE}

    标志
    可能是
    SHGFP\u类型\u默认值

    handle
    可能是
    NULL

    retval
    我想应该是一个
    bool
    ,但我不确定

    所有答案都来自您以前的链接。

    例如

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

    以防有人需要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}}
    


    golang.org/x/sys/windows
    现在有一个用于
    SHGetKnownFolderPath
    的包装器,因此这更容易:

    主程序包
    进口(
    “fmt”
    “golang.org/x/sys/windows”
    )
    func main(){
    路径,错误:=windows.KnownFolderPath(windows.FOLDERID\u字体,0)
    如果错误!=零{
    fmt.Println(错误)
    返回
    }
    fmt.Println(路径)
    }
    
    为什么要投否决票?如何改进该问题?返回值的类型为
    HRESULT
    。可以使用宏
    succeed(hr)
    FAILED(hr)
    @Tim-thank将其转换为布尔成功代码,这很有意义。太棒了,谢谢!仍在努力理解这一点。给我一天:)很好的回答。。。只添加代码对新开发人员没有帮助。。。如果您能添加流程的详细信息,那就太好了
    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}}