你可以使用golang如何获取Windows上所有驱动器的列表?

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

How can I get a listing of all drives on Windows using golang?

问题

我想让我的程序在Windows系统上遍历所有驱动器,并搜索特定的文件类型。目前,我可以运行程序并传递一个起始驱动器字母,但我希望它可以自动搜索所有驱动器。目前,我需要像这样做:

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

我希望程序能够获取所有驱动器的列表,并在不需要用户指定驱动器字母的情况下遍历它们。使用Go语言是否可以实现这一点?

类似于这个问题 https://stackoverflow.com/questions/15350641/listing-all-physical-drives-windows,但是使用Go语言而不是C语言。

英文:

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 https://stackoverflow.com/questions/15350641/listing-all-physical-drives-windows but using Go instead of C.

答案1

得分: 14

你可以调用函数GetLogicalDrives,并根据位图匹配字母。

类似这样的代码:

package main

import (
	"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 {
		// 处理错误
	} 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
}
英文:

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

Something like:

package main

import (
	"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
}

答案2

得分: 10

你可以使用gopsutil库:

package main

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

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

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

答案3

得分: 6

最简单的方法是编写自己的函数,尝试打开由Volker提到的“drive”文件夹。

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
}

最终的函数将返回一个字符串切片,其中包含可以成功打开的驱动器字母。

英文:

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
}

答案4

得分: 5

或者你可以直接调用 GetLogicalDriveStrings 函数:

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 {
		// 处理缓冲区,你需要对其进行分割
	}
}

以上是要翻译的内容。

英文:

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

答案5

得分: 2

你可以使用windows包:

package main

import (
   "golang.org/x/sys/windows"
   "strings"
   "unicode/utf16"
)

func drives() ([]string, error) {
   n, e := windows.GetLogicalDriveStrings(0, nil)
   if e != nil { return nil, e }
   a := make([]uint16, n)
   windows.GetLogicalDriveStrings(n, &a[0])
   s := string(utf16.Decode(a))
   return strings.Split(strings.TrimRight(s, "\x00"), "\x00"), nil
}

func main() {
   a, e := drives()
   if e != nil {
      panic(e)
   }
   for _, s := range a {
      println(s)
   }
}

https://pkg.go.dev/golang.org/x/sys/windows#GetLogicalDriveStrings

英文:

You can use the windows package:

package main

import (
   "golang.org/x/sys/windows"
   "strings"
   "unicode/utf16"
)

func drives() ([]string, error) {
   n, e := windows.GetLogicalDriveStrings(0, nil)
   if e != nil { return nil, e }
   a := make([]uint16, n)
   windows.GetLogicalDriveStrings(n, &a[0])
   s := string(utf16.Decode(a))
   return strings.Split(strings.TrimRight(s, "\x00"), "\x00"), nil
}

func main() {
   a, e := drives()
   if e != nil {
      panic(e)
   }
   for _, s := range a {
      println(s)
   }
}

https://pkg.go.dev/golang.org/x/sys/windows#GetLogicalDriveStrings

huangapple
  • 本文由 发表于 2014年4月17日 16:25:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/23128148.html
匿名

发表评论

匿名网友

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

确定