diff --git a/tools/rust/cargo-proton-bundle/src/bundle/build_msi.rs b/tools/rust/cargo-proton-bundle/src/bundle/build_msi.rs deleted file mode 100644 index 3a53d55f2..000000000 --- a/tools/rust/cargo-proton-bundle/src/bundle/build_msi.rs +++ /dev/null @@ -1,3 +0,0 @@ -use semver::Version; -use Platform; -use WIX; diff --git a/tools/rust/cargo-proton-bundle/src/bundle/msi_bundle.rs b/tools/rust/cargo-proton-bundle/src/bundle/msi_bundle.rs index 35d5843ff..1c3f7fd8b 100644 --- a/tools/rust/cargo-proton-bundle/src/bundle/msi_bundle.rs +++ b/tools/rust/cargo-proton-bundle/src/bundle/msi_bundle.rs @@ -1,35 +1,15 @@ +#[warn(dead_code)] use super::common; use super::settings::Settings; use super::wix; use crate::ResultExt; -use cab; -use dirs; -use msi; + use slog::Drain; use slog_term; use std; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::env; -use std::ffi::OsStr; -use std::fs; -use std::io::{self, Write}; -use std::path::{Path, PathBuf}; -use uuid::Uuid; +use std::collections::BTreeMap; -type Package = msi::Package; - -// Don't add more files to a cabinet folder that already has this many bytes: -const CABINET_FOLDER_SIZE_LIMIT: u64 = 0x8000; -// The maximum number of resource files we'll put in one cabinet: -const CABINET_MAX_FILES: usize = 1000; -// The maximum number of data bytes we'll put in one cabinet: -const CABINET_MAX_SIZE: u64 = 0x1000_0000; - -// File table attribute indicating that a file is "vital": -const FILE_ATTR_VITAL: u16 = 0x200; - -// The name of the installer package's sole Feature: -const MAIN_FEATURE_NAME: &str = "MainFeature"; +use std::path::PathBuf; // Info about a resource file (including the main executable) in the bundle. struct ResourceInfo { @@ -57,152 +37,28 @@ struct DirectoryInfo { files: Vec, } -// Info about a CAB archive within the installer package. -struct CabinetInfo { - // The stream name for this cabinet. - name: String, - // The resource files that are in this cabinet. - resources: Vec, -} - pub fn bundle_project(settings: &Settings) -> crate::Result> { common::print_warning("MSI bundle support is still experimental.")?; - let msi_name = format!("{}.msi", settings.bundle_name()); - common::print_bundling(&msi_name)?; - let base_dir = settings.project_out_directory().join("bundle/msi"); - let msi_path = base_dir.join(&msi_name); - let mut package = - new_empty_package(&msi_path).chain_err(|| "Failed to initialize MSI package")?; - - // Generate package metadata: - // let guid = generate_package_guid(settings); - // set_summary_info(&mut package, guid, settings); - // create_property_table(&mut package, guid, settings) - // .chain_err(|| "Failed to generate Property table")?; - - // Copy resource files into package: let mut resources = collect_resource_info(settings).chain_err(|| "Failed to collect resource file information")?; let _directories = collect_directory_info(settings, &mut resources) .chain_err(|| "Failed to collect resource directory information")?; - let cabinets = divide_resources_into_cabinets(resources); - generate_resource_cabinets(&mut package, &cabinets) - .chain_err(|| "Failed to generate resource cabinets")?; let decorator = slog_term::TermDecorator::new().build(); let drain = slog_term::CompactFormat::new(decorator).build(); let drain = std::sync::Mutex::new(drain).fuse(); let logger = slog::Logger::root(drain, o!()); let wix_path = PathBuf::from("./WixTools"); - wix::get_and_extract_wix(&logger, &wix_path)?; + if !wix_path.exists() { + wix::get_and_extract_wix(&logger, &wix_path)?; + } - wix::build_wix_app_installer(&logger, &settings, &wix_path, base_dir)?; + let msi_path = wix::build_wix_app_installer(&logger, &settings, &wix_path)?; - // Set up installer database tables: - // create_directory_table(&mut package, &directories) - // .chain_err(|| "Failed to generate Directory table")?; - // create_feature_table(&mut package, settings).chain_err(|| "Failed to generate Feature table")?; - // create_component_table(&mut package, guid, &directories) - // .chain_err(|| "Failed to generate Component table")?; - // create_feature_components_table(&mut package, &directories) - // .chain_err(|| "Failed to generate FeatureComponents table")?; - // create_media_table(&mut package, &cabinets).chain_err(|| "Failed to generate Media table")?; - // create_file_table(&mut package, &cabinets).chain_err(|| "Failed to generate File table")?; - // // TODO: Create other needed tables. - - // // Create app icon: - // package.create_table( - // "Icon", - // vec![ - // msi::Column::build("Name").primary_key().id_string(72), - // msi::Column::build("Data").binary(), - // ], - // )?; - // let icon_name = format!("{}.ico", settings.binary_name()); - // { - // let stream_name = format!("Icon.{}", icon_name); - // let mut stream = package.write_stream(&stream_name)?; - // create_app_icon(&mut stream, settings)?; - // } - // package.insert_rows(msi::Insert::into("Icon").row(vec![ - // msi::Value::Str(icon_name.clone()), - // msi::Value::from("Name"), - // ]))?; - - // package.flush()?; Ok(vec![msi_path]) } -fn new_empty_package(msi_path: &Path) -> crate::Result { - if let Some(parent) = msi_path.parent() { - fs::create_dir_all(&parent).chain_err(|| format!("Failed to create directory {:?}", parent))?; - } - let msi_file = fs::OpenOptions::new() - .read(true) - .write(true) - .create(true) - .truncate(true) - .open(msi_path) - .chain_err(|| format!("Failed to create file {:?}", msi_path))?; - let package = msi::Package::create(msi::PackageType::Installer, msi_file)?; - Ok(package) -} - -// Populates the summary metadata for the package from the bundle settings. -fn set_summary_info(package: &mut Package, package_guid: Uuid, settings: &Settings) { - let summary_info = package.summary_info_mut(); - summary_info.set_creation_time_to_now(); - summary_info.set_subject(settings.bundle_name().to_string()); - summary_info.set_uuid(package_guid); - summary_info.set_comments(settings.short_description().to_string()); - if let Some(authors) = settings.authors_comma_separated() { - summary_info.set_author(authors); - } - let creating_app = format!("cargo-bundle v{}", crate_version!()); - summary_info.set_creating_application(creating_app); -} - -// Creates and populates the `Property` database table for the package. -fn create_property_table( - package: &mut Package, - package_guid: Uuid, - settings: &Settings, -) -> crate::Result<()> { - let authors = settings.authors_comma_separated().unwrap_or(String::new()); - package.create_table( - "Property", - vec![ - msi::Column::build("Property").primary_key().id_string(72), - msi::Column::build("Value").text_string(0), - ], - )?; - package.insert_rows( - msi::Insert::into("Property") - .row(vec![ - msi::Value::from("Manufacturer"), - msi::Value::Str(authors), - ]) - .row(vec![ - msi::Value::from("ProductCode"), - msi::Value::from(package_guid), - ]) - .row(vec![ - msi::Value::from("ProductLanguage"), - msi::Value::from(msi::Language::from_tag("en-US")), - ]) - .row(vec![ - msi::Value::from("ProductName"), - msi::Value::from(settings.bundle_name()), - ]) - .row(vec![ - msi::Value::from("ProductVersion"), - msi::Value::from(settings.version_string()), - ]), - )?; - Ok(()) -} - // Returns a list of `ResourceInfo` structs for the binary executable and all // the resource files that should be included in the package. fn collect_resource_info(settings: &Settings) -> crate::Result> { @@ -284,339 +140,3 @@ fn collect_directory_info( } Ok(dir_map.into_iter().map(|(_k, v)| v).collect()) } - -// Divides up the list of resource into some number of cabinets, subject to a -// few contraints: 1) no one cabinet will have two resources with the same -// filename, 2) no one cabinet will have more than `CABINET_MAX_FILES` files -// in it, and 3) no one cabinet will contain mroe than `CABINET_MAX_SIZE` -// bytes of data (unless that cabinet consists of a single file that is -// already bigger than that). -fn divide_resources_into_cabinets(mut resources: Vec) -> Vec { - let mut cabinets = Vec::new(); - while !resources.is_empty() { - let mut filenames = HashSet::::new(); - let mut total_size = 0; - let mut leftovers = Vec::::new(); - let mut cabinet = CabinetInfo { - name: format!("rsrc{:04}.cab", cabinets.len()), - resources: Vec::new(), - }; - for resource in resources.into_iter() { - if cabinet.resources.len() >= CABINET_MAX_FILES - || (!cabinet.resources.is_empty() && total_size + resource.size > CABINET_MAX_SIZE) - || filenames.contains(&resource.filename) - { - leftovers.push(resource); - } else { - filenames.insert(resource.filename.clone()); - total_size += resource.size; - cabinet.resources.push(resource); - } - } - cabinets.push(cabinet); - resources = leftovers; - } - cabinets -} - -// Creates the CAB archives within the package that contain the binary -// execuable and all the resource files. -fn generate_resource_cabinets( - package: &mut Package, - cabinets: &[CabinetInfo], -) -> crate::Result<()> { - for cabinet_info in cabinets.iter() { - let mut builder = cab::CabinetBuilder::new(); - let mut file_map = HashMap::::new(); - let mut resource_index: usize = 0; - while resource_index < cabinet_info.resources.len() { - let folder = builder.add_folder(cab::CompressionType::MsZip); - let mut folder_size: u64 = 0; - while resource_index < cabinet_info.resources.len() && folder_size < CABINET_FOLDER_SIZE_LIMIT - { - let resource = &cabinet_info.resources[resource_index]; - folder_size += resource.size; - folder.add_file(resource.filename.as_str()); - debug_assert!(!file_map.contains_key(&resource.filename)); - file_map.insert(resource.filename.clone(), &resource.source_path); - resource_index += 1; - } - } - let stream = package.write_stream(cabinet_info.name.as_str())?; - let mut cabinet_writer = builder.build(stream)?; - while let Some(mut file_writer) = cabinet_writer.next_file()? { - debug_assert!(file_map.contains_key(file_writer.file_name())); - let file_path = file_map.get(file_writer.file_name()).unwrap(); - let mut file = fs::File::open(file_path)?; - io::copy(&mut file, &mut file_writer)?; - } - cabinet_writer.finish()?; - } - Ok(()) -} - -// Creates and populates the `Directory` database table for the package. -fn create_directory_table( - package: &mut Package, - directories: &[DirectoryInfo], -) -> crate::Result<()> { - package.create_table( - "Directory", - vec![ - msi::Column::build("Directory").primary_key().id_string(72), - msi::Column::build("Directory_Parent") - .nullable() - .foreign_key("Directory", 1) - .id_string(72), - msi::Column::build("DefaultDir") - .category(msi::Category::DefaultDir) - .string(255), - ], - )?; - let mut rows = Vec::new(); - for directory in directories.iter() { - rows.push(vec![ - msi::Value::Str(directory.key.clone()), - msi::Value::Str(directory.parent_key.clone()), - msi::Value::Str(directory.name.clone()), - ]); - } - package.insert_rows( - msi::Insert::into("Directory") - .row(vec![ - msi::Value::from("TARGETDIR"), - msi::Value::Null, - msi::Value::from("SourceDir"), - ]) - .row(vec![ - msi::Value::from("ProgramFilesFolder"), - msi::Value::from("TARGETDIR"), - msi::Value::from("."), - ]) - .rows(rows), - )?; - Ok(()) -} - -// Creates and populates the `Feature` database table for the package. The -// package will have a single main feature that installs everything. -fn create_feature_table(package: &mut Package, settings: &Settings) -> crate::Result<()> { - package.create_table( - "Feature", - vec![ - msi::Column::build("Feature").primary_key().id_string(38), - msi::Column::build("Feature_Parent") - .nullable() - .foreign_key("Feature", 1) - .id_string(38), - msi::Column::build("Title").nullable().text_string(64), - msi::Column::build("Description") - .nullable() - .text_string(255), - msi::Column::build("Display") - .nullable() - .range(0, 0x7fff) - .int16(), - msi::Column::build("Level").range(0, 0x7fff).int16(), - msi::Column::build("Directory_") - .nullable() - .foreign_key("Directory", 1) - .id_string(72), - msi::Column::build("Attributes").int16(), - ], - )?; - package.insert_rows(msi::Insert::into("Feature").row(vec![ - msi::Value::from(MAIN_FEATURE_NAME), - msi::Value::Null, - msi::Value::from(settings.bundle_name()), - msi::Value::Null, - msi::Value::Int(1), - msi::Value::Int(3), - msi::Value::from("INSTALLDIR"), - msi::Value::Int(0), - ]))?; - Ok(()) -} - -// Creates and populates the `Component` database table for the package. One -// component is created for each subdirectory under in the install dir. -fn create_component_table( - package: &mut Package, - package_guid: Uuid, - directories: &[DirectoryInfo], -) -> crate::Result<()> { - package.create_table( - "Component", - vec![ - msi::Column::build("Component").primary_key().id_string(72), - msi::Column::build("ComponentId") - .nullable() - .category(msi::Category::Guid) - .string(38), - msi::Column::build("Directory_") - .nullable() - .foreign_key("Directory", 1) - .id_string(72), - msi::Column::build("Attributes").int16(), - msi::Column::build("Condition") - .nullable() - .category(msi::Category::Condition) - .string(255), - msi::Column::build("KeyPath").nullable().id_string(72), - ], - )?; - let mut rows = Vec::new(); - for directory in directories.iter() { - if !directory.files.is_empty() { - let hash_input = directory.files.join("/"); - rows.push(vec![ - msi::Value::Str(directory.key.clone()), - msi::Value::from(Uuid::new_v5(&package_guid, &hash_input)), - msi::Value::Str(directory.key.clone()), - msi::Value::Int(0), - msi::Value::Null, - msi::Value::Str(directory.files[0].clone()), - ]); - } - } - package.insert_rows(msi::Insert::into("Component").rows(rows))?; - Ok(()) -} - -// Creates and populates the `FeatureComponents` database table for the -// package. All components are added to the package's single main feature. -fn create_feature_components_table( - package: &mut Package, - directories: &[DirectoryInfo], -) -> crate::Result<()> { - package.create_table( - "FeatureComponents", - vec![ - msi::Column::build("Feature_") - .primary_key() - .foreign_key("Component", 1) - .id_string(38), - msi::Column::build("Component_") - .primary_key() - .foreign_key("Component", 1) - .id_string(72), - ], - )?; - let mut rows = Vec::new(); - for directory in directories.iter() { - if !directory.files.is_empty() { - rows.push(vec![ - msi::Value::from(MAIN_FEATURE_NAME), - msi::Value::Str(directory.key.clone()), - ]); - } - } - package.insert_rows(msi::Insert::into("FeatureComponents").rows(rows))?; - Ok(()) -} - -// Creates and populates the `Media` database table for the package, with one -// entry for each CAB archive within the package. -fn create_media_table(package: &mut Package, cabinets: &[CabinetInfo]) -> crate::Result<()> { - package.create_table( - "Media", - vec![ - msi::Column::build("DiskId") - .primary_key() - .range(1, 0x7fff) - .int16(), - msi::Column::build("LastSequence").range(0, 0x7fff).int16(), - msi::Column::build("DiskPrompt").nullable().text_string(64), - msi::Column::build("Cabinet") - .nullable() - .category(msi::Category::Cabinet) - .string(255), - msi::Column::build("VolumeLabel").nullable().text_string(32), - msi::Column::build("Source") - .nullable() - .category(msi::Category::Property) - .string(32), - ], - )?; - let mut disk_id: i32 = 0; - let mut last_seq: i32 = 0; - let mut rows = Vec::new(); - for cabinet in cabinets.iter() { - disk_id += 1; - last_seq += cabinet.resources.len() as i32; - rows.push(vec![ - msi::Value::Int(disk_id), - msi::Value::Int(last_seq), - msi::Value::Null, - msi::Value::Str(format!("#{}", cabinet.name)), - msi::Value::Null, - msi::Value::Null, - ]); - } - package.insert_rows(msi::Insert::into("Media").rows(rows))?; - Ok(()) -} - -// Creates and populates the `File` database table for the package, with one -// entry for each resource file to be installed (including the main -// executable). -fn create_file_table(package: &mut Package, cabinets: &[CabinetInfo]) -> crate::Result<()> { - package.create_table( - "File", - vec![ - msi::Column::build("File").primary_key().id_string(72), - msi::Column::build("Component_") - .foreign_key("Component", 1) - .id_string(72), - msi::Column::build("FileName") - .category(msi::Category::Filename) - .string(255), - msi::Column::build("FileSize").range(0, 0x7fffffff).int32(), - msi::Column::build("Version") - .nullable() - .category(msi::Category::Version) - .string(72), - msi::Column::build("Language") - .nullable() - .category(msi::Category::Language) - .string(20), - msi::Column::build("Attributes") - .nullable() - .range(0, 0x7fff) - .int16(), - msi::Column::build("Sequence").range(1, 0x7fff).int16(), - ], - )?; - let mut rows = Vec::new(); - let mut sequence: i32 = 1; - for cabinet in cabinets.iter() { - for resource in cabinet.resources.iter() { - rows.push(vec![ - msi::Value::Str(format!("r{:04}", sequence)), - msi::Value::Str(resource.component_key.clone()), - msi::Value::Str(resource.filename.clone()), - msi::Value::Int(resource.size as i32), - msi::Value::Null, - msi::Value::Null, - msi::Value::from(FILE_ATTR_VITAL), - msi::Value::Int(sequence), - ]); - sequence += 1; - } - } - package.insert_rows(msi::Insert::into("File").rows(rows))?; - Ok(()) -} - -fn create_app_icon(writer: &mut W, settings: &Settings) -> crate::Result<()> { - // Prefer ICO files. - for icon_path in settings.icon_files() { - let icon_path = icon_path?; - if icon_path.extension() == Some(OsStr::new("ico")) { - io::copy(&mut fs::File::open(icon_path)?, writer)?; - return Ok(()); - } - } - // TODO: Convert from other formats. - Ok(()) -} diff --git a/tools/rust/cargo-proton-bundle/src/bundle/templates/main.wxs b/tools/rust/cargo-proton-bundle/src/bundle/templates/main.wxs index ec8238026..dbf2101f2 100644 --- a/tools/rust/cargo-proton-bundle/src/bundle/templates/main.wxs +++ b/tools/rust/cargo-proton-bundle/src/bundle/templates/main.wxs @@ -20,30 +20,20 @@ - + - - + @@ -58,7 +48,7 @@ AllowAdvertise="no" Display="expand" Absent="disallow"> - + - - - - \ No newline at end of file diff --git a/tools/rust/cargo-proton-bundle/src/bundle/wix.rs b/tools/rust/cargo-proton-bundle/src/bundle/wix.rs index 4f9929962..d85944111 100644 --- a/tools/rust/cargo-proton-bundle/src/bundle/wix.rs +++ b/tools/rust/cargo-proton-bundle/src/bundle/wix.rs @@ -16,17 +16,19 @@ pub const WIX_URL: &str = "https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311-binaries.zip"; pub const WIX_SHA256: &str = "37f0a533b0978a454efb5dc3bd3598becf9660aaf4287e55bf68ca6b527d051d"; -const VC_REDIST_X86_URL: &str = - "https://download.visualstudio.microsoft.com/download/pr/c8edbb87-c7ec-4500-a461-71e8912d25e9/99ba493d660597490cbb8b3211d2cae4/vc_redist.x86.exe"; +// For Cross Platform Complilation. -const VC_REDIST_X86_SHA256: &str = - "3a43e8a55a3f3e4b73d01872c16d47a19dd825756784f4580187309e7d1fcb74"; +// const VC_REDIST_X86_URL: &str = +// "https://download.visualstudio.microsoft.com/download/pr/c8edbb87-c7ec-4500-a461-71e8912d25e9/99ba493d660597490cbb8b3211d2cae4/vc_redist.x86.exe"; -const VC_REDIST_X64_URL: &str = - "https://download.visualstudio.microsoft.com/download/pr/9e04d214-5a9d-4515-9960-3d71398d98c3/1e1e62ab57bbb4bf5199e8ce88f040be/vc_redist.x64.exe"; +// const VC_REDIST_X86_SHA256: &str = +// "3a43e8a55a3f3e4b73d01872c16d47a19dd825756784f4580187309e7d1fcb74"; -const VC_REDIST_X64_SHA256: &str = - "d6cd2445f68815fe02489fafe0127819e44851e26dfbe702612bc0d223cbbc2b"; +// const VC_REDIST_X64_URL: &str = +// "https://download.visualstudio.microsoft.com/download/pr/9e04d214-5a9d-4515-9960-3d71398d98c3/1e1e62ab57bbb4bf5199e8ce88f040be/vc_redist.x64.exe"; + +// const VC_REDIST_X64_SHA256: &str = +// "d6cd2445f68815fe02489fafe0127819e44851e26dfbe702612bc0d223cbbc2b"; // A v4 UUID that was generated specifically for cargo-bundle, to be used as a // namespace for generating v5 UUIDs from bundle identifier strings. @@ -72,11 +74,7 @@ fn download_and_verify(logger: &Logger, url: &str, hash: &str) -> Result } fn app_installer_dir(settings: &Settings) -> PathBuf { - let arch = match settings.binary_arch() { - "i686-pc-windows-msvc" => "x86", - "x86_64-pc-windows-msvc" => "amd64", - target => panic!("unsupported target: {}", target), - }; + let arch = "x64"; settings.project_out_directory().to_path_buf().join(format!( "{}.{}.msi", @@ -126,56 +124,58 @@ pub fn get_and_extract_wix(logger: &Logger, path: &Path) -> Result<(), String> { extract_zip(&data, path) } -fn run_heat_exe( - logger: &Logger, - wix_toolset_path: &Path, - build_path: &Path, - harvest_dir: &Path, - platform: &str, -) -> Result<(), String> { - let mut args = vec!["dir"]; +// For if bundler needs DLL files. - let harvest_str = harvest_dir.display().to_string(); +// fn run_heat_exe( +// logger: &Logger, +// wix_toolset_path: &Path, +// build_path: &Path, +// harvest_dir: &Path, +// platform: &str, +// ) -> Result<(), String> { +// let mut args = vec!["dir"]; - args.push(&harvest_str); - args.push("-platform"); - args.push(platform); - args.push("-cg"); - args.push("AppFiles"); - args.push("-dr"); - args.push("APPLICATIONFOLDER"); - args.push("-gg"); - args.push("-srd"); - args.push("-out"); - args.push("appdir.wxs"); - args.push("-var"); - args.push("var.SourceDir"); +// let harvest_str = harvest_dir.display().to_string(); - let heat_exe = wix_toolset_path.join("head.exe"); +// args.push(&harvest_str); +// args.push("-platform"); +// args.push(platform); +// args.push("-cg"); +// args.push("AppFiles"); +// args.push("-dr"); +// args.push("APPLICATIONFOLDER"); +// args.push("-gg"); +// args.push("-srd"); +// args.push("-out"); +// args.push("appdir.wxs"); +// args.push("-var"); +// args.push("var.SourceDir"); - let mut cmd = Command::new(&heat_exe) - .args(&args) - .stdout(Stdio::piped()) - .current_dir(build_path) - .spawn() - .expect("error running heat.exe"); +// let heat_exe = wix_toolset_path.join("heat.exe"); - { - let stdout = cmd.stdout.as_mut().unwrap(); - let reader = BufReader::new(stdout); +// let mut cmd = Command::new(&heat_exe) +// .args(&args) +// .stdout(Stdio::piped()) +// .current_dir(build_path) +// .spawn() +// .expect("error running heat.exe"); - for line in reader.lines() { - info!(logger, "{}", line.unwrap()); - } - } +// { +// let stdout = cmd.stdout.as_mut().unwrap(); +// let reader = BufReader::new(stdout); - let status = cmd.wait().unwrap(); - if status.success() { - Ok(()) - } else { - Err("error running heat.exe".to_string()) - } -} +// for line in reader.lines() { +// info!(logger, "{}", line.unwrap()); +// } +// } + +// let status = cmd.wait().unwrap(); +// if status.success() { +// Ok(()) +// } else { +// Err("error running heat.exe".to_string()) +// } +// } fn run_candle( settings: &Settings, @@ -187,10 +187,6 @@ fn run_candle( let arch = "x64"; let args = vec![ - "-ext".to_string(), - "WixBalExtension".to_string(), - "-ext".to_string(), - "WixUtilExtension".to_string(), "-arch".to_string(), arch.to_string(), wxs_file_name.to_string(), @@ -229,7 +225,7 @@ fn run_light( build_path: &Path, wixobjs: &[&str], output_path: &Path, -) -> Result<(), String> { +) -> Result { let light_exe = wix_toolset_path.join("light.exe"); let mut args: Vec = vec!["-o".to_string(), output_path.display().to_string()]; @@ -257,7 +253,7 @@ fn run_light( let status = cmd.wait().unwrap(); if status.success() { - Ok(()) + Ok(output_path.to_path_buf()) } else { Err("error running light.exe".to_string()) } @@ -267,15 +263,10 @@ pub fn build_wix_app_installer( logger: &Logger, settings: &Settings, wix_toolset_path: &Path, - current_dir: PathBuf, -) -> Result<(), String> { - let arch = match settings.binary_arch() { - "i686-pc-windows-msvc" => "x86", - "x86_64-pc-windows-msvc" => "x64", - target => return Err(format!("unsupported target: {}", target)), - }; +) -> Result { + let arch = "x64"; - info!(logger, "Target: {}", settings.binary_arch()); + info!(logger, "Target: {}", arch); let output_path = settings.project_out_directory().join("wix").join(arch); @@ -283,36 +274,24 @@ pub fn build_wix_app_installer( data.insert("product_name", settings.bundle_name()); data.insert("version", settings.version_string()); - let upgrade_code = if arch == "x86" { - Uuid::new_v5( - &uuid::NAMESPACE_DNS, - format!("{}.app.x64", &settings.bundle_name()).as_str(), - ) - .to_string() - } else if arch == "x64" { - Uuid::new_v5( - &uuid::NAMESPACE_DNS, - format!("{}.app.x64", &settings.bundle_name()).as_str(), - ) - .to_string() - } else { - return Err(format!("unsupported target: {}", arch)); - }; + let manufacturer = settings.bundle_identifier().to_string(); + data.insert("manufacturer", manufacturer.as_str()); + let upgrade_code = Uuid::new_v5( + &uuid::NAMESPACE_DNS, + format!("{}.app.x64", &settings.binary_name()).as_str(), + ) + .to_string(); - data.insert("upgrade_code", &upgrade_code); + data.insert("upgrade_code", &upgrade_code.as_str()); let path_guid = generate_package_guid(settings).to_string(); data.insert("path_component_guid", &path_guid.as_str()); - let app_exe_name = settings - .binary_path() - .file_name() - .unwrap() - .to_string_lossy() - .to_string(); + let app_exe_name = settings.binary_name().to_string(); data.insert("app_exe_name", &app_exe_name); let app_exe_source = settings.binary_path().display().to_string(); + data.insert("app_exe_source", &app_exe_source); let temp = HANDLEBARS @@ -328,23 +307,15 @@ pub fn build_wix_app_installer( let main_wxs_path = output_path.join("main.wxs"); write(&main_wxs_path, temp).or_else(|e| Err(e.to_string()))?; - run_heat_exe( - logger, - &wix_toolset_path, - &output_path, - &Settings::get_workspace_dir(¤t_dir), - arch, - )?; - - let input_basenames = vec!["main", "appdir"]; + let input_basenames = vec!["main"]; for basename in &input_basenames { let wxs = format!("{}.wxs", basename); run_candle(settings, logger, &wix_toolset_path, &output_path, &wxs)?; } - let wixobjs = vec!["main.wixobj", "appdir.wixobj"]; - run_light( + let wixobjs = vec!["main.wixobj"]; + let target = run_light( logger, &wix_toolset_path, &output_path, @@ -352,5 +323,5 @@ pub fn build_wix_app_installer( &app_installer_dir(settings), )?; - Ok(()) + Ok(target) }