From fabd72f9f98ef29466fa2244ff5672d2f41003d8 Mon Sep 17 00:00:00 2001 From: Heath Stewart Date: Sat, 22 Oct 2022 08:54:30 -0700 Subject: [PATCH] Add trace example --- .vscode/cspell.json | 1 + Cargo.toml | 5 +++ examples/example.wixproj | 1 + examples/example.wxs | 1 + examples/skip/lib.rs | 4 ++ examples/trace/lib.rs | 83 ++++++++++++++++++++++++++++++++++++++++ examples/trace/trace.wxs | 14 +++++++ 7 files changed, 109 insertions(+) create mode 100644 examples/trace/lib.rs create mode 100644 examples/trace/trace.wxs diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 1511416..7da6549 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -11,6 +11,7 @@ "LPSTR", "msbuild", "msica", + "msidb", "msiexec", "MSIHANDLE", "msvc", diff --git a/Cargo.toml b/Cargo.toml index af852d4..a9ce960 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,8 @@ path = "examples/deferred/lib.rs" name = "skip" crate-type = ["cdylib"] path = "examples/skip/lib.rs" + +[[example]] +name = "trace" +crate-type = ["cdylib"] +path = "examples/trace/lib.rs" diff --git a/examples/example.wixproj b/examples/example.wixproj index 3eea41d..abb8792 100644 --- a/examples/example.wixproj +++ b/examples/example.wixproj @@ -24,6 +24,7 @@ + diff --git a/examples/example.wxs b/examples/example.wxs index 7c0d9a9..c34ac1b 100644 --- a/examples/example.wxs +++ b/examples/example.wxs @@ -38,5 +38,6 @@ + diff --git a/examples/skip/lib.rs b/examples/skip/lib.rs index 9329fcd..6459f11 100644 --- a/examples/skip/lib.rs +++ b/examples/skip/lib.rs @@ -17,6 +17,10 @@ pub extern "C" fn SkipExampleCustomAction(session: Session) -> CustomActionResul } true => { let data = session.property("CustomActionData")?; + if data.is_empty() { + return Succeed; + } + // Unnecessarily parsing the string demonstrates using ? for any possible error. let data = data.parse::()?; if data == 2 { diff --git a/examples/trace/lib.rs b/examples/trace/lib.rs new file mode 100644 index 0000000..3fdd8a6 --- /dev/null +++ b/examples/trace/lib.rs @@ -0,0 +1,83 @@ +// Copyright 2022 Heath Stewart. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +use msica::CustomActionResult::Succeed; +use msica::*; + +const MSIDB_CUSTOM_ACTION_TYPE_DLL: i32 = 1; +const MSIDB_CUSTOM_ACTION_TYPE_CONTINUE: i32 = 64; +const MSIDB_CUSTOM_ACTION_TYPE_IN_SCRIPT: i32 = 1024; + +#[no_mangle] +pub extern "C" fn TraceExampleCustomAction(session: Session) -> CustomActionResult { + let trace_deferred_actions: Vec<&'static str> = vec!["InstallFiles"]; + + let database = session.database(); + + let custom_actions = + database.open_view("SELECT `Action`, `Type`, `Source`, `Target` FROM `CustomAction`")?; + custom_actions.execute(None)?; + + let sequence_table = + database.open_view("SELECT `Action`, `Sequence` FROM `InstallExecuteSequence`")?; + sequence_table.execute(None)?; + + let sequence_table_ordered = database.open_view( + "SELECT `Action`, `Sequence` FROM `InstallExecuteSequence` ORDER BY `Sequence`", + )?; + sequence_table_ordered.execute(None)?; + for action in sequence_table_ordered { + let name = action.string_data(1)?; + let sequence = action.integer_data(2).unwrap_or_default(); + + if trace_deferred_actions.contains(&name.as_ref()) { + let action = format!("{}Pre", name); + session.set_property(action.as_ref(), Some(action.as_ref()))?; + insert_row(&custom_actions, &sequence_table, action, sequence - 1)?; + + let action = format!("{}Post", name); + session.set_property(action.as_ref(), Some(action.as_ref()))?; + insert_row(&custom_actions, &sequence_table, action, sequence + 1)?; + } + } + + Succeed +} + +#[no_mangle] +pub extern "C" fn TraceExampleCustomActionDeferred(session: Session) -> CustomActionResult { + let data = session.property("CustomActionData")?; + let record = Record::with_fields(Some("Running [1]"), vec![Field::StringData(data)])?; + session.message(MessageType::Info, &record); + + Succeed +} + +fn insert_row( + custom_actions: &View, + sequence_table: &View, + name: String, + sequence: i32, +) -> Result<()> { + const TYPE: i32 = MSIDB_CUSTOM_ACTION_TYPE_DLL + + MSIDB_CUSTOM_ACTION_TYPE_IN_SCRIPT + + MSIDB_CUSTOM_ACTION_TYPE_CONTINUE; + + let custom_action = Record::with_fields( + None, + vec![ + Field::StringData(name.clone()), + Field::IntegerData(TYPE), + Field::StringData("TraceExample".to_owned()), + Field::StringData("TraceExampleCustomActionDeferred".to_owned()), + ], + )?; + custom_actions.modify(ModifyMode::InsertTemporary, &custom_action)?; + + let action = Record::with_fields( + None, + vec![Field::StringData(name), Field::IntegerData(sequence)], + )?; + sequence_table.modify(ModifyMode::InsertTemporary, &action)?; + Ok(()) +} diff --git a/examples/trace/trace.wxs b/examples/trace/trace.wxs new file mode 100644 index 0000000..d593d48 --- /dev/null +++ b/examples/trace/trace.wxs @@ -0,0 +1,14 @@ + + + + + + + + + + +