Session

Struct Session 

Source
pub struct Session { /* private fields */ }
Expand description

A Windows Installer session passed to custom actions.

§Example

use msica::prelude::*;
const ERROR_SUCCESS: u32 = 0;

#[no_mangle]
pub extern "C" fn MyCustomAction(session: Session) -> u32 {
    let record = Record::with_fields(
        Some("this is [1] [2]"),
        vec![Field::IntegerData(1), Field::StringData("example".to_owned())],
    ).expect("failed to create record");
    session.message(MessageType::User, &record);
    ERROR_SUCCESS
}

Implementations§

Source§

impl Session

Source

pub fn database(&self) -> Database

Returns the active database for the installation. This function returns a read-only Database.

Examples found in repository?
examples/deferred/lib.rs (line 8)
7pub extern "C" fn DeferredExampleCustomAction(session: Session) -> CustomActionResult {
8    let database = session.database();
9    let view = database
10        .open_view("SELECT `Cardinal`, `Ordinal` FROM `DeferredExample` ORDER BY `Cardinal`")?;
11
12    // Add another row.
13    view.modify(
14        ModifyMode::InsertTemporary,
15        &Record::with_fields(
16            None,
17            vec![
18                Field::IntegerData(100),
19                Field::StringData("last".to_string()),
20            ],
21        )?,
22    )?;
23
24    // Schedule custom actions for each row.
25    view.execute(None)?;
26    for record in view {
27        let data = format!(
28            "{}\t{}",
29            record.integer_data(1).unwrap_or(0),
30            record.string_data(2)?,
31        );
32        session.do_deferred_action("DeferredExampleCustomActionDeferred", &data)?;
33    }
34    Success
35}
Source

pub fn do_action(&self, action: Option<&str>) -> Result<()>

Runs the specified immediate custom action, or schedules a deferred custom action. If None the default action is run e.g., INSTALL.

To schedule a deferred custom action with its CustomActionData, call Session::do_deferred_action().

Source

pub fn do_deferred_action( &self, action: &str, custom_action_data: &str, ) -> Result<()>

Sets custom action data and schedules a deferred custom action.

§Example
use msica::prelude::*;
const ERROR_SUCCESS: u32 = 0;

#[no_mangle]
pub extern "C" fn MyCustomAction(session: Session) -> u32 {
    for i in 0..5 {
        session.do_deferred_action("MyDeferredCustomAction", &i.to_string());
    }
    ERROR_SUCCESS
}

#[no_mangle]
pub extern "C" fn MyDeferredCustomAction(session: Session) -> u32 {
    let data = session.property("CustomActionData").expect("failed to get CustomActionData");
    let record = Record::try_from(data).expect("failed to create record");
    session.message(MessageType::Info, &record);
    ERROR_SUCCESS
}
Examples found in repository?
examples/skip/lib.rs (line 15)
7pub extern "C" fn SkipExampleCustomAction(session: Session) -> CustomActionResult {
8    let deferred = session.mode(RunMode::Scheduled);
9    match deferred {
10        false => {
11            let data = session.property("SKIP")?;
12            if data == "1" {
13                return Skip;
14            }
15            session.do_deferred_action("SkipExampleCustomActionDeferred", data.as_str())?;
16        }
17        true => {
18            let data = session.property("CustomActionData")?;
19            if data.is_empty() {
20                return Success;
21            }
22
23            // Unnecessarily parsing the string demonstrates using ? for any possible error.
24            let data = data.parse::<u32>()?;
25            if data == 2 {
26                return Skip;
27            }
28        }
29    }
30    Success
31}
More examples
Hide additional examples
examples/deferred/lib.rs (line 32)
7pub extern "C" fn DeferredExampleCustomAction(session: Session) -> CustomActionResult {
8    let database = session.database();
9    let view = database
10        .open_view("SELECT `Cardinal`, `Ordinal` FROM `DeferredExample` ORDER BY `Cardinal`")?;
11
12    // Add another row.
13    view.modify(
14        ModifyMode::InsertTemporary,
15        &Record::with_fields(
16            None,
17            vec![
18                Field::IntegerData(100),
19                Field::StringData("last".to_string()),
20            ],
21        )?,
22    )?;
23
24    // Schedule custom actions for each row.
25    view.execute(None)?;
26    for record in view {
27        let data = format!(
28            "{}\t{}",
29            record.integer_data(1).unwrap_or(0),
30            record.string_data(2)?,
31        );
32        session.do_deferred_action("DeferredExampleCustomActionDeferred", &data)?;
33    }
34    Success
35}
Source

pub fn language(&self) -> u16

The numeric language ID used by the current install session.

Source

pub fn message(&self, kind: MessageType, record: &Record) -> i32

Processes a Record within the Session.

Examples found in repository?
examples/deferred/lib.rs (line 50)
38pub extern "C" fn DeferredExampleCustomActionDeferred(session: Session) -> CustomActionResult {
39    // Process the custom action data passed by the immediate custom action.
40    // This data is always made available in a property named "CustomActionData".
41    let data = session.property("CustomActionData")?;
42    let fields: Vec<&str> = data.split('\t').collect();
43    let record = Record::with_fields(
44        Some("Running the [2] ([1]) deferred custom action"),
45        vec![
46            Field::StringData(fields[0].to_string()),
47            Field::StringData(fields[1].to_string()),
48        ],
49    )?;
50    session.message(MessageType::Info, &record);
51    Success
52}
Source

pub fn mode(&self, mode: RunMode) -> bool

Returns a boolean indicating whether the specific property passed into the function is currently set (true) or not set (false).

§Example

You could use the same custom action entry point for scheduling and executing deferred actions:

use msica::prelude::*;
const ERROR_SUCCESS: u32 = 0;

#[no_mangle]
pub extern "C" fn MyCustomAction(session: Session) -> u32 {
    if !session.mode(RunMode::Scheduled) {
        session.do_deferred_action("MyCustomAction", "Hello, world!");
    } else {
        let data = session.property("CustomActionData").expect("failed to get CustomActionData");
        let record = Record::with_fields(Some(data.as_str()), vec![]).expect("failed to create record");
        session.message(MessageType::User, &record);
    }
    ERROR_SUCCESS
}
Examples found in repository?
examples/skip/lib.rs (line 8)
7pub extern "C" fn SkipExampleCustomAction(session: Session) -> CustomActionResult {
8    let deferred = session.mode(RunMode::Scheduled);
9    match deferred {
10        false => {
11            let data = session.property("SKIP")?;
12            if data == "1" {
13                return Skip;
14            }
15            session.do_deferred_action("SkipExampleCustomActionDeferred", data.as_str())?;
16        }
17        true => {
18            let data = session.property("CustomActionData")?;
19            if data.is_empty() {
20                return Success;
21            }
22
23            // Unnecessarily parsing the string demonstrates using ? for any possible error.
24            let data = data.parse::<u32>()?;
25            if data == 2 {
26                return Skip;
27            }
28        }
29    }
30    Success
31}
Source

pub fn property(&self, name: &str) -> Result<String>

Gets the value of the named property, or an empty string if undefined.

Examples found in repository?
examples/deferred/lib.rs (line 41)
38pub extern "C" fn DeferredExampleCustomActionDeferred(session: Session) -> CustomActionResult {
39    // Process the custom action data passed by the immediate custom action.
40    // This data is always made available in a property named "CustomActionData".
41    let data = session.property("CustomActionData")?;
42    let fields: Vec<&str> = data.split('\t').collect();
43    let record = Record::with_fields(
44        Some("Running the [2] ([1]) deferred custom action"),
45        vec![
46            Field::StringData(fields[0].to_string()),
47            Field::StringData(fields[1].to_string()),
48        ],
49    )?;
50    session.message(MessageType::Info, &record);
51    Success
52}
More examples
Hide additional examples
examples/skip/lib.rs (line 11)
7pub extern "C" fn SkipExampleCustomAction(session: Session) -> CustomActionResult {
8    let deferred = session.mode(RunMode::Scheduled);
9    match deferred {
10        false => {
11            let data = session.property("SKIP")?;
12            if data == "1" {
13                return Skip;
14            }
15            session.do_deferred_action("SkipExampleCustomActionDeferred", data.as_str())?;
16        }
17        true => {
18            let data = session.property("CustomActionData")?;
19            if data.is_empty() {
20                return Success;
21            }
22
23            // Unnecessarily parsing the string demonstrates using ? for any possible error.
24            let data = data.parse::<u32>()?;
25            if data == 2 {
26                return Skip;
27            }
28        }
29    }
30    Success
31}
Source

pub fn set_property(&self, name: &str, value: Option<&str>) -> Result<()>

Sets the value of the named property. Pass None to clear the field.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.