2013-07-30 20 views
5

Cerco di trovare la cartella dei font su un'installazione di Windows. AFAICS il modo proposto è di chiamare SHGetKnownFolderPath in Shell32.dll con KNOWNFOLDERID impostato su FOLDERID_Fonts.Chiamare la funzione windows (ottenere la directory dei font)

non ho idea di cosa passare alla funzione Call nel seguente codice:

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

Qualche idea? (Immagino che una soluzione per ora sarebbe di attenersi a %windir%\Fonts, ma mi piacerebbe ottenere una soluzione adeguata).

Riferimenti:

+0

Perché il downvote? Cosa posso fare per migliorare la domanda? – topskip

risposta

8

Per esempio,

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

uscita:

Font Folder: C:\Windows\Fonts 
+0

Fantastico, grazie! Sto ancora cercando di capire questo. Dammi un giorno :) – topskip

+1

Bella risposta ... l'aggiunta di un codice non aiuterebbe i nuovi sviluppatori ... Sarebbe bello che tu aggiungessi i dettagli del tuo processo – Baba

-1

folderId per la directory dei font è {FD228CB7-AE11-4AE3-864C-16F3910AB8FE}

flags può probabilmente essere SHGFP_TYPE_DEFAULT

handle può probabilmente essere NULL

retvalpenso dovrebbe essere un bool, ma non sono sicuro.

Tutte le risposte provengono dal tuo SHGetFolderPath function collegato in precedenza.

+0

Il valore restituito è di tipo 'HRESULT'. Può essere convertito in un codice di successo booleano usando le macro 'SUCCEEDED (hr)' o 'FAILED (hr)'. – IInspectable

+0

@Tim Grazie, ha senso. – Intermernet

2

Solo nel caso qualcuno ha bisogno l'id cartella per i documenti in formato golang:

Sostituire questo nel codice di esempio di 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}}

vedere

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

Problemi correlati