github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/commands/build/nsis_installer.go (about) 1 package build 2 3 import ( 4 "fmt" 5 "path" 6 "path/filepath" 7 "strings" 8 9 "github.com/AlpineAIO/wails/v2/internal/fs" 10 "github.com/AlpineAIO/wails/v2/internal/shell" 11 "github.com/AlpineAIO/wails/v2/internal/webview2runtime" 12 "github.com/AlpineAIO/wails/v2/pkg/buildassets" 13 ) 14 15 const ( 16 nsisTypeSingle = "single" 17 nsisTypeMultiple = "multiple" 18 19 nsisFolder = "windows/installer" 20 nsisProjectFile = "project.nsi" 21 nsisToolsFile = "wails_tools.nsh" 22 nsisWebView2SetupFile = "tmp/MicrosoftEdgeWebview2Setup.exe" 23 ) 24 25 func GenerateNSISInstaller(options *Options, amd64Binary string, arm64Binary string) error { 26 outputLogger := options.Logger 27 outputLogger.Println("Creating NSIS installer\n------------------------------") 28 29 // Ensure the file exists, if not the template will be written. 30 projectFile := path.Join(nsisFolder, nsisProjectFile) 31 if _, err := buildassets.ReadFile(options.ProjectData, projectFile); err != nil { 32 return fmt.Errorf("Unable to generate NSIS installer project template: %w", err) 33 } 34 35 // Write the resolved nsis tools 36 toolsFile := path.Join(nsisFolder, nsisToolsFile) 37 if _, err := buildassets.ReadOriginalFileWithProjectDataAndSave(options.ProjectData, toolsFile); err != nil { 38 return fmt.Errorf("Unable to generate NSIS tools file: %w", err) 39 } 40 41 // Write the WebView2 SetupFile 42 webviewSetup := buildassets.GetLocalPath(options.ProjectData, path.Join(nsisFolder, nsisWebView2SetupFile)) 43 if dir := filepath.Dir(webviewSetup); !fs.DirExists(dir) { 44 if err := fs.MkDirs(dir, 0o755); err != nil { 45 return err 46 } 47 } 48 49 if err := webview2runtime.WriteInstallerToFile(webviewSetup); err != nil { 50 return fmt.Errorf("Unable to write WebView2 Bootstrapper Setup: %w", err) 51 } 52 53 if !shell.CommandExists("makensis") { 54 outputLogger.Println("Warning: Cannot create installer: makensis not found") 55 return nil 56 } 57 58 nsisType := options.ProjectData.NSISType 59 if nsisType == nsisTypeSingle && (amd64Binary == "" || arm64Binary == "") { 60 nsisType = "" 61 } 62 63 switch nsisType { 64 case "": 65 fallthrough 66 case nsisTypeMultiple: 67 if amd64Binary != "" { 68 if err := makeNSIS(options, "amd64", amd64Binary, ""); err != nil { 69 return err 70 } 71 } 72 73 if arm64Binary != "" { 74 if err := makeNSIS(options, "arm64", "", arm64Binary); err != nil { 75 return err 76 } 77 } 78 79 case nsisTypeSingle: 80 if err := makeNSIS(options, "single", amd64Binary, arm64Binary); err != nil { 81 return err 82 } 83 default: 84 return fmt.Errorf("Unsupported nsisType: %s", nsisType) 85 } 86 87 return nil 88 } 89 90 func makeNSIS(options *Options, installerKind string, amd64Binary string, arm64Binary string) error { 91 verbose := options.Verbosity == VERBOSE 92 outputLogger := options.Logger 93 94 outputLogger.Print(" - Building '%s' installer: ", installerKind) 95 args := []string{} 96 if amd64Binary != "" { 97 args = append(args, "-DARG_WAILS_AMD64_BINARY="+amd64Binary) 98 } 99 if arm64Binary != "" { 100 args = append(args, "-DARG_WAILS_ARM64_BINARY="+arm64Binary) 101 } 102 args = append(args, nsisProjectFile) 103 104 if verbose { 105 outputLogger.Println("makensis %s", strings.Join(args, " ")) 106 } 107 108 installerDir := buildassets.GetLocalPath(options.ProjectData, nsisFolder) 109 stdOut, stdErr, err := shell.RunCommand(installerDir, "makensis", args...) 110 if err != nil || verbose { 111 outputLogger.Println(stdOut) 112 outputLogger.Println(stdErr) 113 } 114 if err != nil { 115 return fmt.Errorf("Error during creation of the installer: %w", err) 116 } 117 outputLogger.Println("Done.") 118 return nil 119 }