131 lines
3.1 KiB
Go
131 lines
3.1 KiB
Go
package platform
|
||
|
||
import (
|
||
"context"
|
||
"io"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
|
||
"golang.org/x/sys/windows/registry"
|
||
)
|
||
|
||
// WindowsPlatform Windows 平台实现
|
||
type WindowsPlatform struct {
|
||
homeDir string
|
||
}
|
||
|
||
// NewWindowsPlatform 创建 Windows 平台实例
|
||
func NewWindowsPlatform() *WindowsPlatform {
|
||
return &WindowsPlatform{
|
||
homeDir: os.Getenv("USERPROFILE"),
|
||
}
|
||
}
|
||
|
||
func (p *WindowsPlatform) OS() string { return "windows" }
|
||
func (p *WindowsPlatform) Arch() string { return os.Getenv("PROCESSOR_ARCHITECTURE") }
|
||
|
||
func (p *WindowsPlatform) HomeDir() string {
|
||
return p.homeDir
|
||
}
|
||
|
||
func (p *WindowsPlatform) ConfigDir() string {
|
||
if dir := os.Getenv("APPDATA"); dir != "" {
|
||
return dir
|
||
}
|
||
return p.homeDir + "\\AppData\\Roaming"
|
||
}
|
||
|
||
func (p *WindowsPlatform) DataDir() string {
|
||
if dir := os.Getenv("LOCALAPPDATA"); dir != "" {
|
||
return dir
|
||
}
|
||
return p.homeDir + "\\AppData\\Local"
|
||
}
|
||
|
||
func (p *WindowsPlatform) GetEnvVar(key string) string {
|
||
return os.Getenv(key)
|
||
}
|
||
|
||
func (p *WindowsPlatform) SetEnvVar(ctx context.Context, key, value string) error {
|
||
cmd := exec.CommandContext(ctx, "setx", key, value)
|
||
return cmd.Run()
|
||
}
|
||
|
||
func (p *WindowsPlatform) AddToPath(ctx context.Context, dir string) error {
|
||
currentPath := os.Getenv("PATH")
|
||
newPath := dir + ";" + currentPath
|
||
return p.SetEnvVar(ctx, "PATH", newPath)
|
||
}
|
||
|
||
func (p *WindowsPlatform) IsAdmin() bool {
|
||
// 检查 Windows 上是否以管理员身份运行
|
||
cmd := exec.Command("net", "session")
|
||
err := cmd.Run()
|
||
return err == nil
|
||
}
|
||
|
||
func (p *WindowsPlatform) PackageManagers() []string {
|
||
var pms []string
|
||
if _, err := exec.LookPath("scoop"); err == nil {
|
||
pms = append(pms, "scoop")
|
||
}
|
||
if _, err := exec.LookPath("choco"); err == nil {
|
||
pms = append(pms, "chocolatey")
|
||
}
|
||
if _, err := exec.LookPath("winget"); err == nil {
|
||
pms = append(pms, "winget")
|
||
}
|
||
return pms
|
||
}
|
||
|
||
func (p *WindowsPlatform) DefaultShell() string {
|
||
if _, err := exec.LookPath("pwsh"); err == nil {
|
||
return "pwsh" // PowerShell 7+ 版本
|
||
}
|
||
return "powershell" // Windows PowerShell 5.1
|
||
}
|
||
|
||
// InstallFont 安装字体
|
||
func (p *WindowsPlatform) InstallFont(ctx context.Context, fontPath string) error {
|
||
// 目标路径为 C:\Users\<User>\AppData\Local\Microsoft\Windows\Fonts
|
||
// 也可以使用 C:\Users\<User>\AppData\Roaming\Microsoft\Windows\Fonts,但 Local 更合适
|
||
destDir := filepath.Join(os.Getenv("LOCALAPPDATA"), "Microsoft", "Windows", "Fonts")
|
||
|
||
// 确保目标目录存在
|
||
os.MkdirAll(destDir, 0755)
|
||
|
||
// 获取字体文件名
|
||
fontName := filepath.Base(fontPath)
|
||
// 目标路径
|
||
destPath := filepath.Join(destDir, fontName)
|
||
|
||
// 复制字体文件到目标路径
|
||
input, err := os.Open(fontPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer input.Close()
|
||
|
||
output, err := os.Create(destPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
defer output.Close()
|
||
_, err = io.Copy(output, input)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 写注册表以注册字体
|
||
key, _, err := registry.CreateKey(registry.CURRENT_USER, `Software\Microsoft\Windows NT\CurrentVersion\Fonts`, registry.ALL_ACCESS)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer key.Close()
|
||
regName := fontName + " (TrueType)"
|
||
|
||
return key.SetStringValue(regName, destPath)
|
||
}
|