Golang实现直接从微软商店启用自动更新功能

Golang实现直接从微软商店启用自动更新功能 我注意到许多SDK现在正转向Windows应用商店以实现自动更新,例如PowerShell和Python。我们能否为Go语言实现同样的功能?

1 回复

更多关于Golang实现直接从微软商店启用自动更新功能的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中实现类似微软商店的自动更新功能,可以通过打包为MSIX格式并集成应用安装服务来实现。以下是具体实现方案:

1. 创建MSIX打包配置

<!-- AppxManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
         xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
         xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10">
    <Identity Name="YourApp" 
              Version="1.0.0.0" 
              Publisher="CN=YourCompany"/>
    
    <Properties>
        <DisplayName>Your Go Application</DisplayName>
        <PublisherDisplayName>Your Company</PublisherDisplayName>
    </Properties>
    
    <Dependencies>
        <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0"/>
    </Dependencies>
    
    <Resources>
        <Resource Language="en-us"/>
    </Resources>
    
    <Applications>
        <Application Id="App" Executable="yourapp.exe">
            <uap:VisualElements DisplayName="Your App"/>
        </Application>
    </Applications>
</Package>

2. Go程序集成更新检查

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "runtime"
    "syscall"
    "time"
    "golang.org/x/sys/windows"
)

// 更新配置结构
type UpdateConfig struct {
    Version     string `json:"version"`
    DownloadURL string `json:"download_url"`
    ReleaseDate string `json:"release_date"`
    Changelog   string `json:"changelog"`
}

// 检查更新
func CheckForUpdates(currentVersion string) (*UpdateConfig, error) {
    // 从你的API或微软商店API获取更新信息
    resp, err := http.Get("https://api.yourdomain.com/updates/latest")
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    
    var update UpdateConfig
    if err := json.Unmarshal(body, &update); err != nil {
        return nil, err
    }
    
    // 比较版本
    if update.Version > currentVersion {
        return &update, nil
    }
    
    return nil, nil
}

// 通过应用安装服务触发更新
func TriggerStoreUpdate() error {
    const (
        CLSID_AppInstaller = "{e6b9627a-8a65-4b2d-973e-8e7d2335d06d}"
        IID_IAppInstaller  = "{efc0b4d8-b2d5-4c8b-87b5-8a5c5b9c7a9b}"
    )
    
    var appInstaller *windows.IUnknown
    hr := windows.CoCreateInstance(
        windows.StringToUTF16Ptr(CLSID_AppInstaller),
        nil,
        windows.CLSCTX_ALL,
        windows.StringToUTF16Ptr(IID_IAppInstaller),
        &appInstaller,
    )
    
    if hr != windows.S_OK {
        return fmt.Errorf("failed to create AppInstaller instance: 0x%x", hr)
    }
    
    // 调用更新方法
    // 实际实现需要定义完整的COM接口
    return nil
}

// 后台更新服务
func UpdateService() {
    ticker := time.NewTicker(24 * time.Hour) // 每天检查一次
    defer ticker.Stop()
    
    for range ticker.C {
        update, err := CheckForUpdates("1.0.0.0")
        if err != nil {
            continue
        }
        
        if update != nil {
            // 通知用户有可用更新
            notifyUpdate(update)
        }
    }
}

func notifyUpdate(update *UpdateConfig) {
    // 使用Windows通知或系统托盘图标通知用户
    fmt.Printf("新版本 %s 可用!\n更新内容:%s\n", 
        update.Version, update.Changelog)
}

func main() {
    // 启动更新服务
    go UpdateService()
    
    // 你的主程序逻辑
    fmt.Println("应用程序运行中...")
    select {}
}

3. 构建和部署脚本

# build.ps1 - 构建和打包脚本
$env:GOOS = "windows"
$env:GOARCH = "amd64"

# 构建Go程序
go build -ldflags "-H=windowsgui" -o yourapp.exe main.go

# 使用MSIX打包工具
# 需要安装 Windows App SDK 和 MSIX 打包工具
MakeAppx.exe pack `
    /d ".\appx\" `
    /p "yourapp.msix" `
    /l /v

# 签名(需要证书)
SignTool.exe sign `
    /fd SHA256 `
    /a `
    /tr http://timestamp.digicert.com `
    /td SHA256 `
    yourapp.msix

4. 更新服务器API示例

// update_server.go
package main

import (
    "encoding/json"
    "net/http"
    "time"
)

var latestUpdate = UpdateConfig{
    Version:     "1.1.0.0",
    DownloadURL: "https://store.microsoft.com/product/yourapp",
    ReleaseDate: time.Now().Format("2006-01-02"),
    Changelog:   "修复了若干问题,提升了性能",
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(latestUpdate)
}

func main() {
    http.HandleFunc("/updates/latest", updateHandler)
    http.ListenAndServe(":8080", nil)
}

5. 使用Windows应用安装器API

// 使用Windows Runtime API与商店交互
// +build windows

package store

import (
    "syscall"
    "unsafe"
)

var (
    modwindowsappruntime = syscall.NewLazyDLL("windows.appruntime.dll")
    
    procGetCurrentPackageInfo = modwindowsappruntime.NewProc("GetCurrentPackageInfo")
)

// 检查是否从微软商店安装
func IsStoreInstall() bool {
    var length uint32
    var buffer uintptr
    
    // 调用Windows API检查包信息
    hr, _, _ := procGetCurrentPackageInfo.Call(
        0, // flags
        uintptr(unsafe.Pointer(&length)),
        uintptr(unsafe.Pointer(&buffer)),
    )
    
    return hr == 0 && length > 0
}

这个实现方案通过MSIX打包、集成Windows应用安装服务、定期检查更新服务器来实现自动更新功能。关键点包括正确的MSIX配置、COM接口调用处理更新流程,以及后台服务持续监控新版本。

回到顶部