英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论