在Go语言中检测Windows版本以确定启动文件夹的方法是什么?

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

Detect windows version in Go to figure out the starup folder

问题

有没有办法检测主机操作系统是XP、Vista、7、8还是10?
runtime.GOOS只返回"windows"。

这是因为我想在启动文件夹中操作文件。

在Windows Vista、7、8、10中,它位于:

%appdata%\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

在Windows XP中,它位于:

Documents and Settings\%username%\Start Menu\Programs\Startup

英文:

Is there anyway to detect if the host operating system is XP, Vista, 7, 8, or 10?
runtime.GOOS just returns "windows".

The reason for this is because I'm trying to manipulate files in the startup folder.

On windows vista, 7, 8, 10 it's located at:

%appdata%\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

On windows XP it's located at:

Documents and Settings\%username%\Start Menu\Programs\Startup

答案1

得分: 6

为什么不使用Windows注册表?

这是返回的结果:

PS C:\Users\Adamar\Desktop> .\WindowsVersion.exe
CurrentVersion: 6.3
ProductName: Windows Server 2016 Standard Evaluation
CurrentMajorVersionNumber: 10
CurrentMinorVersionNumber: 0
CurrentVersion: 14393

尽管在最新版本的Windows中,您必须读取以下键来获取版本号:CurrentMajorVersionNumber和CurrentMinorVersionNumber。

英文:

Why not use the windows registry?

https://godoc.org/golang.org/x/sys/windows/registry

https://stackoverflow.com/questions/36998532/how-to-return-a-default-value-from-windows-registry-with-golang

package main

import (
	"golang.org/x/sys/windows/registry"
	"log"
	"fmt"
)

func main() {

	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
	if err != nil {
		log.Fatal(err)
	}
	defer k.Close()

	cv, _, err := k.GetStringValue("CurrentVersion")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("CurrentVersion: %s\n", cv)

	pn , _, err := k.GetStringValue("ProductName")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("ProductName: %s\n", pn)

	maj, _, err := k.GetIntegerValue("CurrentMajorVersionNumber")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("CurrentMajorVersionNumber: %d\n", maj)

	min, _, err := k.GetIntegerValue("CurrentMinorVersionNumber")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("CurrentMinorVersionNumber: %d\n", min)

	cb, _, err := k.GetStringValue("CurrentBuild")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("CurrentVersion: %s\n", cb)    
}

This returns:

PS C:\Users\Adamar\Desktop> .\WindowsVersion.exe
CurrentVersion: 6.3
ProductName: Windows Server 2016 Standard Evaluation
CurrentMajorVersionNumber: 10
CurrentMinorVersionNumber: 0
CurrentVersion: 14393

Although in the newest version of windows you have to read the following keys to get the version: CurrentMajorVersionNumber & CurrentMinorVersionNumber

答案2

得分: 3

如果你想获取Windows版本,请使用w32库,这是一个纯Go语言的Win32 API封装。

它提供了w32.RtlGetVersion()函数,该函数返回一个结构体,其中包含了MajorVersion和MinorVersion等信息。这些信息可以报告程序所运行的Windows版本。

你不能依赖于w32.GetVersion()函数。理论上,你可以使用这个Windows版本表来确定你所在的位置,但GetVersion只适用于具有正确清单文件的应用程序,该清单文件指明该程序适用于Windows 10。如果你只是使用go build进行编译而没有清单文件,GetVersion仍然会报告Windows 8(Windows版本6.2)。

package main

import (
	"fmt"
	"github.com/gonutz/w32/v2"
)

func main() {
	v := w32.RtlGetVersion()
	fmt.Println(v.MajorVersion, v.MinorVersion)
}

然而,正如其他人正确指出的那样,你应该使用适当的Win32 API函数来获取特殊文件夹。

英文:

If you want to get the Windows version, use the w32 library, a pure Go Win32 API wrapper.

It has w32.RtlGetVersion() which returns a struct containing (besides other things) MajorVersion and MinorVersion. These will report the correct Windows version that the program is running on.

You cannot rely on the function w32.GetVersion(). Theoretically you could use this Windows version table to know where you are but GetVersion only works for applications that have a correct manifest file which says that the program is for Windows 10. If you just compile with go build without a manifest file, GetVersion will still report Windows 8 (Windows version 6.2).

package main

import (
	"fmt"
	"github.com/gonutz/w32/v2"
)

func main() {
	v := w32.RtlGetVersion()
	fmt.Println(v.MajorVersion, v.MinorVersion)
}

Note however, as others have stated correctly, that you should really be using the appropriate Win32 API functions to get the special folders in your case.

答案3

得分: 1

我知道这是旧的,但在撰写本文时(2023年1月),您可以使用RtlGetNtVersionNumbers函数,该函数由Go官方维护。

package main

import (
	"fmt"

	"golang.org/x/sys/windows"
)

func main() {
	maj, min, patch := windows.RtlGetNtVersionNumbers()
	fmt.Println(maj, min, patch)
}

对于我来说,它打印出10 0 22621

英文:

I know that this is old, but at the time of this writing (Jan 2023), you can use RtlGetNtVersionNumbers, which is officially maintained by Go.

package main

import (
	"fmt"

	"golang.org/x/sys/windows"
)

func main() {
	maj, min, patch := windows.RtlGetNtVersionNumbers()
	fmt.Println(maj, min, patch)
}

which for me prints 10 0 22621.

答案4

得分: 0

根据Jörg W Mittag的精彩评论,这应该能帮助你入门:

//go:build windows

package main

import (
	"fmt"

	"golang.org/x/sys/windows"
)

func main() {
	path, err := windows.KnownFolderPath(windows.FOLDERID_Startup, 0)
	fmt.Println(err, path)
}

有关更多信息,请参阅syscall_windows.gozknownfolderids_windows.go,网址为https://cs.opensource.google/go/x/sys/+/master:windows

请注意,最后一个支持WinXP的Go版本是1.10,当前版本是1.19,并且支持最后两个版本,因此截至2023-01-10,最后一个支持的版本是1.18。
我的意思是,使其在WinXP上工作的需求是没有意义的:使用Go 1.14+构建的程序甚至无法在该平台上启动。

英文:

Based on excellent on-point comments from Jörg W Mittag, this should make you started:

//go:build windows

package main

import (
	"fmt"

	"golang.org/x/sys/windows"
)

func main() {
	path, err := windows.KnownFolderPath(windows.FOLDERID_Startup, 0)
	fmt.Println(err, path)
}

See syscall_windows.go and zknownfolderids_windows.go at <https://cs.opensource.google/go/x/sys/+/master:windows> for more info.


Note that the last version of Go to support WinXP was 1.10, the current one is 1.19, and the support is provided for the two last versions, hence the last supported version as of now, 2023-01-10, is 1.18.
I mean, the need to make it work on WinXP is moot: a program built for Windows using Go 1.14+ won't even start on that platform.

huangapple
  • 本文由 发表于 2017年6月5日 15:32:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/44363911.html
匿名

发表评论

匿名网友

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

确定