@ -8,11 +8,11 @@ import (
"fmt"
"fmt"
"os"
"os"
"path/filepath"
"path/filepath"
"strings"
"sync/atomic"
"sync/atomic"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.org/x/sys/windows/registry"
"tailscale.com/util/winutil"
)
)
func init ( ) {
func init ( ) {
@ -65,32 +65,20 @@ func packageTypeWindows() string {
if _ , err := os . Stat ( ` C:\ProgramData\chocolatey\lib\tailscale ` ) ; err == nil {
if _ , err := os . Stat ( ` C:\ProgramData\chocolatey\lib\tailscale ` ) ; err == nil {
return "choco"
return "choco"
}
}
if msiSentinel := winutil . GetRegInteger ( "MSI" , 0 ) ; msiSentinel == 1 {
return "msi"
}
exe , err := os . Executable ( )
exe , err := os . Executable ( )
if err != nil {
if err != nil {
return ""
return ""
}
}
dir := filepath . Dir ( exe )
dir := filepath . Dir ( exe )
if ! strings . Contains ( dir , "Program Files" ) {
// Atypical. Not worth trying to detect. Likely open
// source tailscaled or a developer running by hand.
return ""
}
nsisUninstaller := filepath . Join ( dir , "Uninstall-Tailscale.exe" )
nsisUninstaller := filepath . Join ( dir , "Uninstall-Tailscale.exe" )
_ , err = os . Stat ( nsisUninstaller )
_ , err = os . Stat ( nsisUninstaller )
if err == nil {
if err == nil {
return "nsis"
return "nsis"
}
}
if os . IsNotExist ( err ) {
// Atypical. Not worth trying to detect. Likely open
_ , cliErr := os . Stat ( filepath . Join ( dir , "tailscale.exe" ) )
// source tailscaled or a developer running by hand.
_ , daemonErr := os . Stat ( filepath . Join ( dir , "tailscaled.exe" ) )
if cliErr == nil && daemonErr == nil {
// Almost certainly MSI.
// We have tailscaled.exe and tailscale.exe
// next to each other in Program Files, but no
// uninstaller.
// TODO(bradfitz,dblohm7): tighter heuristic?
return "msi"
}
}
return ""
return ""
}
}