Golang一键生成Windows安装程序的方法指南

Golang一键生成Windows安装程序的方法指南 我想为我的Web应用程序创建一个一步到位的Windows安装程序,其中需要包含Go,因为该网站是用Go语言编写的。

请问如何在Windows安装程序包中包含Go?

2 回复

您通常不需要包含Go,因为您安装的是已编译的产物,而且Go二进制文件通常是自包含的。甚至不需要安装额外的运行时或编译器。

更多关于Golang一键生成Windows安装程序的方法指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Windows安装程序中包含Go运行时,可以通过以下方式实现:

方法一:使用Go编译为静态二进制文件(推荐)

将Go程序编译为包含所有依赖的静态二进制文件,这样就不需要在安装程序中包含Go运行时:

// 编译命令(在Windows上)
go build -ldflags="-s -w" -o myapp.exe

// 或者编译为完全静态的二进制文件
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o myapp.exe

方法二:使用Inno Setup创建安装程序

创建Inno Setup脚本(setup.iss)来打包你的Go应用程序:

[Setup]
AppName=My Go Application
AppVersion=1.0
DefaultDirName={pf}\MyGoApp
DefaultGroupName=My Go Application
OutputDir=output
OutputBaseFilename=MyGoAppSetup

[Files]
Source: "myapp.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "config.toml"; DestDir: "{app}"; Flags: ignoreversion
Source: "templates\*"; DestDir: "{app}\templates"; Flags: ignoreversion recursesubdirs

[Icons]
Name: "{group}\My Application"; Filename: "{app}\myapp.exe"
Name: "{group}\Uninstall"; Filename: "{uninstallexe}"

方法三:使用NSIS(Nullsoft Scriptable Install System)

创建NSIS脚本打包应用程序:

!include "MUI2.nsh"

Name "My Go Application"
OutFile "MyGoAppSetup.exe"
InstallDir "$PROGRAMFILES\MyGoApp"

!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

!insertmacro MUI_LANGUAGE "English"

Section "Application"
    SetOutPath $INSTDIR
    
    ; 复制Go编译的可执行文件
    File "myapp.exe"
    File "config.toml"
    
    ; 创建开始菜单快捷方式
    CreateDirectory "$SMPROGRAMS\MyGoApp"
    CreateShortCut "$SMPROGRAMS\MyGoApp\MyGoApp.lnk" "$INSTDIR\myapp.exe"
    
    ; 写入卸载信息
    WriteUninstaller "$INSTDIR\uninstall.exe"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\MyGoApp" \
        "DisplayName" "My Go Application"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\MyGoApp" \
        "UninstallString" '"$INSTDIR\uninstall.exe"'
SectionEnd

Section "Uninstall"
    Delete "$INSTDIR\myapp.exe"
    Delete "$INSTDIR\config.toml"
    Delete "$INSTDIR\uninstall.exe"
    RMDir "$INSTDIR"
    
    Delete "$SMPROGRAMS\MyGoApp\MyGoApp.lnk"
    RMDir "$SMPROGRAMS\MyGoApp"
    
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\MyGoApp"
SectionEnd

方法四:使用Go-Winres为EXE添加资源信息

为Go可执行文件添加Windows资源信息:

// 安装winres工具
go install github.com/tc-hib/go-winres@latest

// 创建winres.json配置文件
{
    "RT_ICON": {
        "APP.ico": {
            "16": "icon-16.png",
            "32": "icon-32.png",
            "48": "icon-48.png",
            "256": "icon-256.png"
        }
    },
    "RT_MANIFEST": {
        "APP.exe.manifest": {
            "identity": {
                "name": "MyGoApp",
                "version": "1.0.0.0"
            },
            "description": "My Go Application",
            "minimum-os": "vista"
        }
    }
}

// 生成资源文件
winres make

// 编译时包含资源
go build -ldflags="-s -w -H windowsgui"

方法五:使用Go代码创建自解压安装程序

创建一个Go程序来生成安装包:

package main

import (
    "archive/zip"
    "fmt"
    "io"
    "os"
    "path/filepath"
)

func createInstaller() error {
    // 创建ZIP文件
    zipFile, err := os.Create("installer.zip")
    if err != nil {
        return err
    }
    defer zipFile.Close()

    writer := zip.NewWriter(zipFile)
    defer writer.Close()

    // 添加文件到ZIP
    files := []string{"myapp.exe", "config.toml", "README.md"}
    for _, file := range files {
        err := addFileToZip(writer, file)
        if err != nil {
            return err
        }
    }

    fmt.Println("安装包创建成功: installer.zip")
    return nil
}

func addFileToZip(w *zip.Writer, filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer file.Close()

    info, err := file.Stat()
    if err != nil {
        return err
    }

    header, err := zip.FileInfoHeader(info)
    if err != nil {
        return err
    }
    header.Name = filename
    header.Method = zip.Deflate

    writer, err := w.CreateHeader(header)
    if err != nil {
        return err
    }

    _, err = io.Copy(writer, file)
    return err
}

func main() {
    if err := createInstaller(); err != nil {
        fmt.Printf("创建安装包失败: %v\n", err)
    }
}

方法六:使用WiX Toolset创建MSI安装包

创建WiX XML配置文件(product.wxs):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="My Go Application" Language="1033" 
             Version="1.0.0.0" Manufacturer="Your Company" 
             UpgradeCode="PUT-GUID-HERE">
        
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
        
        <MajorUpgrade DowngradeErrorMessage="A newer version is already installed." />
        <MediaTemplate EmbedCab="yes" />
        
        <Feature Id="ProductFeature" Title="MyGoApp" Level="1">
            <ComponentGroupRef Id="ProductComponents" />
        </Feature>
    </Product>
    
    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="MyGoApp" />
            </Directory>
        </Directory>
    </Fragment>
    
    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
            <Component Id="MainExecutable" Guid="*">
                <File Id="MyAppExe" Source="myapp.exe" KeyPath="yes" />
                <File Id="ConfigFile" Source="config.toml" />
            </Component>
        </ComponentGroup>
    </Fragment>
</Wix>

编译WiX安装包:

candle.exe product.wxs
light.exe product.wixobj -out MyGoApp.msi

这些方法中,方法一(静态编译)配合方法二(Inno Setup)是最常用的组合,可以创建专业的Windows安装程序而不需要用户单独安装Go运行时。

回到顶部