diff --git a/control/controlclient/hostinfo_windows.go b/control/controlclient/hostinfo_windows.go index 07cb4ce4e..81c438327 100644 --- a/control/controlclient/hostinfo_windows.go +++ b/control/controlclient/hostinfo_windows.go @@ -5,9 +5,9 @@ package controlclient import ( - "os/exec" - "strings" - "syscall" + "fmt" + + "golang.org/x/sys/windows" ) func init() { @@ -15,16 +15,6 @@ func init() { } func osVersionWindows() string { - cmd := exec.Command("cmd", "/c", "ver") - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - out, _ := cmd.Output() // "\nMicrosoft Windows [Version 10.0.19041.388]\n\n" - s := strings.TrimSpace(string(out)) - s = strings.TrimPrefix(s, "Microsoft Windows [") - s = strings.TrimSuffix(s, "]") - - // "Version 10.x.y.z", with "Version" localized. Keep only stuff after the space. - if sp := strings.Index(s, " "); sp != -1 { - s = s[sp+1:] - } - return s // "10.0.19041.388", ideally + major, minor, build := windows.RtlGetNtVersionNumbers() + return fmt.Sprintf("%d.%d.%d", major, minor, build) } diff --git a/control/controlclient/hostinfo_windows_test.go b/control/controlclient/hostinfo_windows_test.go new file mode 100644 index 000000000..edfb9b0c1 --- /dev/null +++ b/control/controlclient/hostinfo_windows_test.go @@ -0,0 +1,28 @@ +// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package controlclient + +import ( + "os/exec" + "regexp" + "testing" +) + +func TestOsVersionWindows(t *testing.T) { + out, err := exec.Command("cmd", "/c", "ver").Output() + if err != nil { + t.Fatalf("`ver` error: %v", err) + } + // Extract the version number from the output, and isolate the first three parts (major.minor.build) + rx := regexp.MustCompile(`(\d+\.\d+\.\d+)(\.\d+)?`) + m := rx.FindStringSubmatch(string(out)) + if m == nil { + t.Fatalf("no version number in `ver` output: %q", out) + } + got := osVersionWindows() + if m[1] != got { + t.Errorf("osVersionWindows got %q want %q", got, m[1]) + } +}