如何使用golang获取Windows上所有驱动器的清单?

I would like my program to iterate through all drives on a Windows system and search for a particular file type. Right now, I can run the program and pass it a drive letter to start from, but I want it to search on all drives automatically. Currently, I would need to do something like this:

C:\> program.exe C:
C:\> program.exe D:
C:\> program.exe E:

I want the program to get a list of all drives and iterate through all of them without the user having to specify the drive letter. Is this possible using Go?

Similar to this question Listing All Physical Drives (Windows) but using Go instead of C.

The easist way is write own function with try to open "drive" folder mentioned by Volker.

import "os"

func getdrives() (r []string){
    for _, drive := range "ABCDEFGHIJKLMNOPQRSTUVWXYZ"{
        f, err := os.Open(string(drive)+":\\")
        if err == nil {
            r = append(r, string(drive))
            f.Close()
        }
    }
    return
}

You can call the function GetLogicalDrives and match the letters according to the bit map.

Something like:

package main

import (
    "akori/files/utils/fs"
    "fmt"
    "syscall"
)

func main() {

    kernel32, _ := syscall.LoadLibrary("kernel32.dll")
    getLogicalDrivesHandle, _ := syscall.GetProcAddress(kernel32, "GetLogicalDrives")

    var drives []string

    if ret, _, callErr := syscall.Syscall(uintptr(getLogicalDrivesHandle), 0, 0, 0, 0); callErr != 0 {
        // handle error
    } else {
        drives = bitsToDrives(uint32(ret))
    }

    fmt.Printf("%v", drives)

}

func bitsToDrives(bitMap uint32) (drives []string) {
    availableDrives := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}

    for i := range availableDrives {
        if bitMap & 1 == 1 {
            drives = append(drives, availableDrives[i])
        }
        bitMap >>= 1
    }

    return
}

Or you can call GetLogicalDriveStrings directly:

package main

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

func main() {
    kernel32, err := syscall.LoadDLL("kernel32.dll")
    getLogicalDriveStringsHandle, err := kernel32.FindProc("GetLogicalDriveStringsA")

    buffer := [1024]byte{}
    bufferSize := uint32(len(buffer))
    drives := []string{}

    hr, _, _ := getLogicalDriveStringsHandle.Call(uintptr(unsafe.Pointer(&bufferSize)), uintptr(unsafe.Pointer(&buffer)))
    if hr == 0 {
        fmt.Print("There was an error")
    } else {
        // Deal with the buffer, you need to split it
    }
}

You can use the gopsutil lib:

package main

import (
    "fmt"
    "github.com/shirou/gopsutil/disk"
)

func main() {
    partitions, _ := disk.Partitions(false)
    for _, partition := range partitions {
        fmt.Println(partition.Mountpoint)
    }
}