Compare commits
3 Commits
119a4d0341
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 930a84a0f6 | |||
| 447d94fdd6 | |||
| f0bd2c0b73 |
@@ -1,5 +1,7 @@
|
|||||||
# WFassoc Core
|
# WFassoc Core
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
This crate provides low level API and high level API for manipulating Windows file associations at the same time.
|
This crate provides low level API and high level API for manipulating Windows file associations at the same time.
|
||||||
For the convenient use of this project, the root module of this crate re-expose high level API.
|
For the convenient use of this project, the root module of this crate re-expose high level API.
|
||||||
So programmers can directly use them.
|
So programmers can directly use them.
|
||||||
@@ -10,3 +12,21 @@ Oppositely, for visiting low level API, please use `lowlevel` module.
|
|||||||
|
|
||||||
If you are a programmer who want to take a deep into the internal implementations,
|
If you are a programmer who want to take a deep into the internal implementations,
|
||||||
see `win32` module and its submodules for detail.
|
see `win32` module and its submodules for detail.
|
||||||
|
|
||||||
|
## Test Notes
|
||||||
|
|
||||||
|
Some tests of this crate may be dangerous because they need to manipulate Windows Registry.
|
||||||
|
So it is highlt recommend that run these tests in sandbox environment.
|
||||||
|
In detailed words, you should run `cargo test --no-run` to build all test first,
|
||||||
|
then fetch the path to executable tests according to this command shown on console.
|
||||||
|
Then execute these executable tests in your sandbox for testing this crate.
|
||||||
|
Additionally, some tests also need Administration permission for testing,
|
||||||
|
because it requires write permission in HKLM.
|
||||||
|
|
||||||
|
If you do not test it with sandbox and administrative environment,
|
||||||
|
test program will assert paniked and tell you how to resolve these issues.
|
||||||
|
|
||||||
|
The reason why do not run `cargo test` in sandbox environment directly,
|
||||||
|
is that `cargo` can not find built tests located in host machine.
|
||||||
|
It will try to fetch all dependencies again and rebuild test in sandbox entirely.
|
||||||
|
So we use this complex way for testing.
|
||||||
|
|||||||
@@ -402,6 +402,7 @@ impl Program {
|
|||||||
|
|
||||||
// Add this progid to file extension "open with" list.
|
// Add this progid to file extension "open with" list.
|
||||||
let ext_key = &mut program_key.ext_key;
|
let ext_key = &mut program_key.ext_key;
|
||||||
|
ext_key.ensure(scope)?;
|
||||||
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
ext_key.add_into_open_with_progids(scope, progid_key.inner())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,9 +439,12 @@ impl Program {
|
|||||||
// there is no need to reset the default open way of file extension.
|
// there is no need to reset the default open way of file extension.
|
||||||
// So we simply remove it from "open with" list.
|
// So we simply remove it from "open with" list.
|
||||||
|
|
||||||
// Remove this ProgId from file extension "open with" list.
|
// Remove this ProgId from file extension "open with" list,
|
||||||
|
// if this file extension is existing
|
||||||
let ext_key = &mut program_key.ext_key;
|
let ext_key = &mut program_key.ext_key;
|
||||||
|
if ext_key.is_exist(scope.into())? {
|
||||||
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
ext_key.remove_from_open_with_progids(scope, progid_key.inner())?;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete ProgId subkey
|
// Delete ProgId subkey
|
||||||
progid_key.delete(scope)?;
|
progid_key.delete(scope)?;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ impl Schema {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_behavior(&self) -> Option<&str> {
|
pub(super) fn get_behavior(&self) -> Option<&str> {
|
||||||
self.icon.as_ref().map(|v| v.as_str())
|
self.behavior.as_ref().map(|v| v.as_str())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_strs(&self) -> &HashMap<String, String> {
|
pub(super) fn get_strs(&self) -> &HashMap<String, String> {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ impl AppPathsKey {
|
|||||||
Ok(key.is_some())
|
Ok(key.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensure this application key is presented in App Paths.
|
/// Ensure this application key is presented in App Paths key.
|
||||||
///
|
///
|
||||||
/// Return true if we newly create this key,
|
/// Return true if we newly create this key,
|
||||||
/// otherwise false indicating there already is an existing key.
|
/// otherwise false indicating there already is an existing key.
|
||||||
@@ -79,15 +79,16 @@ impl AppPathsKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete this application key from App Paths.
|
/// Delete this application key from App Paths key.
|
||||||
///
|
///
|
||||||
/// If there is no such key in App Paths,
|
/// Return true if we successfully delete this key,
|
||||||
/// this function does nothing.
|
/// otherwise false indicating there is no such key (already deleted).
|
||||||
pub fn delete(&mut self, scope: Scope) -> Result<()> {
|
pub fn delete(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
key.parent_key
|
Ok(regext::arbitrarily_delete_subkey_all(
|
||||||
.delete_subkey_all(regext::blank_path_guard(self.key_name.inner())?)?;
|
&key.parent_key,
|
||||||
Ok(())
|
regext::blank_path_guard(self.key_name.inner())?,
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_scope_for_getter(&self, scope: Scope) -> Result<RegKey> {
|
fn open_scope_for_getter(&self, scope: Scope) -> Result<RegKey> {
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ impl ApplicationsKey {
|
|||||||
Ok(key.is_some())
|
Ok(key.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure this application key is presented in Applications key.
|
||||||
|
///
|
||||||
|
/// Return true if we newly create this key,
|
||||||
|
/// otherwise false indicating there already is an existing key.
|
||||||
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
if let None = key.this_key {
|
if let None = key.this_key {
|
||||||
@@ -81,11 +85,16 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self, scope: Scope) -> Result<()> {
|
/// Delete this application key from Applications key.
|
||||||
|
///
|
||||||
|
/// Return true if we successfully delete this key,
|
||||||
|
/// otherwise false indicating there is no such key (already deleted).
|
||||||
|
pub fn delete(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
key.parent_key
|
Ok(regext::arbitrarily_delete_subkey_all(
|
||||||
.delete_subkey_all(regext::blank_path_guard(self.key_name.inner())?)?;
|
&key.parent_key,
|
||||||
Ok(())
|
regext::blank_path_guard(self.key_name.inner())?,
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
@@ -176,7 +185,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete shell and its all subkey.
|
// Delete shell and its all subkey.
|
||||||
key.delete_subkey_all(Self::NAMEOF_SHELL_VERB_PART1)?;
|
regext::arbitrarily_delete_subkey_all(&key, Self::NAMEOF_SHELL_VERB_PART1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +226,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete shell and its all subkey.
|
// Delete shell and its all subkey.
|
||||||
key.delete_subkey_all(Self::NAMEOF_DEFAULT_ICON_PART1)?;
|
regext::arbitrarily_delete_subkey_all(&key, Self::NAMEOF_DEFAULT_ICON_PART1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +257,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_FRIENDLY_APP_NAME)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_FRIENDLY_APP_NAME)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +307,7 @@ impl ApplicationsKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this subkey.
|
// Delete this subkey.
|
||||||
key.delete_subkey_all(Self::NAMEOF_SUPPORTED_TYPES)?;
|
regext::arbitrarily_delete_subkey_all(&key, Self::NAMEOF_SUPPORTED_TYPES)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,7 +329,7 @@ impl ApplicationsKey {
|
|||||||
if flag {
|
if flag {
|
||||||
key.set_value(Self::NAMEOF_NO_OPEN_WITH, &"")?;
|
key.set_value(Self::NAMEOF_NO_OPEN_WITH, &"")?;
|
||||||
} else {
|
} else {
|
||||||
key.delete_value(Self::NAMEOF_NO_OPEN_WITH)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_NO_OPEN_WITH)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ impl ExtKey {
|
|||||||
Ok(key.is_some())
|
Ok(key.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure this file extension key is presented in Classes key.
|
||||||
|
///
|
||||||
|
/// Return true if we newly create this key,
|
||||||
|
/// otherwise false indicating there already is an existing key.
|
||||||
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
if let None = key.this_key {
|
if let None = key.this_key {
|
||||||
@@ -79,11 +83,16 @@ impl ExtKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self, scope: Scope) -> Result<()> {
|
/// Delete this file extension key from Classes key.
|
||||||
|
///
|
||||||
|
/// Return true if we successfully delete this key,
|
||||||
|
/// otherwise false indicating there is no such key (already deleted).
|
||||||
|
pub fn delete(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
key.parent_key
|
Ok(regext::arbitrarily_delete_subkey_all(
|
||||||
.delete_subkey_all(regext::blank_path_guard(self.ext.dotted_inner())?)?;
|
&key.parent_key,
|
||||||
Ok(())
|
regext::blank_path_guard(self.ext.dotted_inner())?,
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
@@ -127,7 +136,7 @@ impl ExtKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_DEFAULT)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_DEFAULT)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +214,10 @@ impl ExtKey {
|
|||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
// Remove given key
|
// Remove given key
|
||||||
open_with_progids_key.delete_value(pid.to_string())?;
|
regext::arbitrarily_delete_value(
|
||||||
|
&open_with_progids_key,
|
||||||
|
regext::blank_path_guard(pid.to_string())?,
|
||||||
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ impl ProgIdKey {
|
|||||||
Ok(key.is_some())
|
Ok(key.is_some())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure this ProgId key is presented in Classes key.
|
||||||
|
///
|
||||||
|
/// Return true if we newly create this key,
|
||||||
|
/// otherwise false indicating there already is an existing key.
|
||||||
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
pub fn ensure(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
if let None = key.this_key {
|
if let None = key.this_key {
|
||||||
@@ -79,11 +83,16 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self, scope: Scope) -> Result<()> {
|
/// Delete this ProgId key from Classes key.
|
||||||
|
///
|
||||||
|
/// Return true if we successfully delete this key,
|
||||||
|
/// otherwise false indicating there is no such key (already deleted).
|
||||||
|
pub fn delete(&mut self, scope: Scope) -> Result<bool> {
|
||||||
let key = self.open_scope_for_write(scope)?;
|
let key = self.open_scope_for_write(scope)?;
|
||||||
key.parent_key
|
Ok(regext::arbitrarily_delete_subkey_all(
|
||||||
.delete_subkey_all(regext::blank_path_guard(self.progid.to_string())?)?;
|
&key.parent_key,
|
||||||
Ok(())
|
regext::blank_path_guard(self.progid.to_string())?,
|
||||||
|
)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// YYC MARK:
|
// YYC MARK:
|
||||||
@@ -129,7 +138,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_DEFAULT)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_DEFAULT)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +218,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete shell and its all subkey.
|
// Delete shell and its all subkey.
|
||||||
key.delete_subkey_all(Self::NAMEOF_SHELL_VERB_PART1)?;
|
regext::arbitrarily_delete_subkey_all(&key, Self::NAMEOF_SHELL_VERB_PART1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +252,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete this key
|
// Delete this key
|
||||||
key.delete_value(Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
regext::arbitrarily_delete_value(&key, Self::NAMEOF_FRIENDLY_TYPE_NAME)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +293,7 @@ impl ProgIdKey {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Delete shell and its all subkey.
|
// Delete shell and its all subkey.
|
||||||
key.delete_subkey_all(Self::NAMEOF_DEFAULT_ICON_PART1)?;
|
regext::arbitrarily_delete_subkey_all(&key, Self::NAMEOF_DEFAULT_ICON_PART1)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,54 @@ pub fn try_get_value<T: FromRegValue, N: AsRef<OsStr>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Delete all tree of given path of given key anyway.
|
||||||
|
///
|
||||||
|
/// This function was invented to fix the shortcoming of [RegKey::delete_subkey_all].
|
||||||
|
/// This function always delete given path of given key no matter it is existing.
|
||||||
|
/// Oppositely, [RegKey::delete_subkey_all] will return error if there is no such path.
|
||||||
|
///
|
||||||
|
/// Return true if we successfully delete this key,
|
||||||
|
/// otherwise false indicating there is no such key (already deleted).
|
||||||
|
pub fn arbitrarily_delete_subkey_all<P: AsRef<OsStr>>(
|
||||||
|
regkey: &RegKey,
|
||||||
|
path: P,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
match regkey.delete_subkey_all(path) {
|
||||||
|
Ok(()) => Ok(true),
|
||||||
|
Err(e) => match e.raw_os_error() {
|
||||||
|
Some(errno) => match errno as u32 {
|
||||||
|
ERROR_FILE_NOT_FOUND => Ok(false),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Delete given value key of given key anyway.
|
||||||
|
///
|
||||||
|
/// This function was invented to fix the shortcoming of [RegKey::delete_value].
|
||||||
|
/// This function always delete given value key of given key no matter it is existing.
|
||||||
|
/// Oppositely, [RegKey::delete_value] will return error if there is no such value key.
|
||||||
|
///
|
||||||
|
/// Return true if we successfully delete this value key,
|
||||||
|
/// otherwise false indicating there is no such value key (already deleted).
|
||||||
|
pub fn arbitrarily_delete_value<N: AsRef<OsStr>>(
|
||||||
|
regkey: &RegKey,
|
||||||
|
name: N,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
match regkey.delete_value(name) {
|
||||||
|
Ok(()) => Ok(true),
|
||||||
|
Err(e) => match e.raw_os_error() {
|
||||||
|
Some(errno) => match errno as u32 {
|
||||||
|
ERROR_FILE_NOT_FOUND => Ok(false),
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
_ => Err(e),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the name of only subkey in given key.
|
/// Get the name of only subkey in given key.
|
||||||
///
|
///
|
||||||
/// If there is only one subkey in given key, the return value is its name.
|
/// If there is only one subkey in given key, the return value is its name.
|
||||||
@@ -110,6 +158,9 @@ pub fn get_all_string_subkey_names(regkey: &RegKey) -> std::io::Result<Vec<Strin
|
|||||||
/// This is very dangerous and may be used by accident.
|
/// This is very dangerous and may be used by accident.
|
||||||
/// So I create this to explicitly indicate this behavior and avoid any mis-type in code.
|
/// So I create this to explicitly indicate this behavior and avoid any mis-type in code.
|
||||||
pub fn clean_all_contents(regkey: &RegKey) -> std::io::Result<()> {
|
pub fn clean_all_contents(regkey: &RegKey) -> std::io::Result<()> {
|
||||||
|
// There is no possibility that this key do not existing,
|
||||||
|
// because what we are cleaning is self content.
|
||||||
|
// So directly use delete_subkey_all is okey.
|
||||||
regkey.delete_subkey_all("")
|
regkey.delete_subkey_all("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,19 @@ pub fn check_sandbox() {
|
|||||||
std::env::var("SANDBOXIE").is_ok(),
|
std::env::var("SANDBOXIE").is_ok(),
|
||||||
concat!(
|
concat!(
|
||||||
"Non-sandbox environment detected. ",
|
"Non-sandbox environment detected. ",
|
||||||
"Executing these test in non-sandbox environment is VERY dangerous. ",
|
"Executing these tests in non-sandbox environment is VERY dangerous. ",
|
||||||
"Please set \"SANDBOXIE\" environment variable to explicitly indicate you are running these test in sandbox environment."
|
"Please set \"SANDBOXIE\" environment variable to explicitly indicate you are running these tests in sandbox environment."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_privilege() {
|
||||||
|
assert!(
|
||||||
|
wfassoc::win32::utilities::has_privilege(),
|
||||||
|
concat!(
|
||||||
|
"You are running test without privilege. ",
|
||||||
|
"These tests must be run with some privilege because it need to manipulate Windows Registry. ",
|
||||||
|
"Please give it privilege in your sandbox environment."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ fn make_valid_schema() -> Schema {
|
|||||||
schema.set_clsid(CLSID);
|
schema.set_clsid(CLSID);
|
||||||
schema.add_str("main_name", "Passoc Application").unwrap();
|
schema.add_str("main_name", "Passoc Application").unwrap();
|
||||||
schema.add_str("ext_name", "Pacfg File").unwrap();
|
schema.add_str("ext_name", "Pacfg File").unwrap();
|
||||||
schema.add_icon("main_icon", r"notepad.exe,0").unwrap();
|
schema.add_icon("main_icon", "notepad.exe,0").unwrap();
|
||||||
schema.add_icon("ext_icon", r"notepad.exe,0").unwrap();
|
schema.add_icon("ext_icon", "notepad.exe,0").unwrap();
|
||||||
schema.add_behavior("main_behavior", "notepad.exe %1").unwrap();
|
schema.add_behavior("main_behavior", "notepad.exe %1").unwrap();
|
||||||
schema.add_behavior("ext_behavior", "notepad.exe %1").unwrap();
|
schema.add_behavior("ext_behavior", "notepad.exe %1").unwrap();
|
||||||
schema.set_name(Some("main_name"));
|
schema.set_name(Some("main_name"));
|
||||||
@@ -29,21 +29,20 @@ fn make_valid_schema() -> Schema {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_schema() {
|
fn test_schema() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
// valid schema -> valid program
|
// valid schema -> valid program
|
||||||
let schema = make_valid_schema();
|
let schema = make_valid_schema();
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_ok());
|
assert!(rv.is_ok());
|
||||||
|
|
||||||
// missing identifier
|
// missing essential parts (schema, path and etc)
|
||||||
let mut schema = Schema::new();
|
let schema = Schema::new();
|
||||||
schema.set_path(APP_PATH);
|
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_err());
|
assert!(rv.is_err());
|
||||||
|
|
||||||
// invalid path
|
// invalid path
|
||||||
let mut schema = Schema::new();
|
let mut schema = make_valid_schema();
|
||||||
schema.set_identifier(IDENTIFIER);
|
|
||||||
schema.set_path(r"C:\");
|
schema.set_path(r"C:\");
|
||||||
let rv = schema.into_program();
|
let rv = schema.into_program();
|
||||||
assert!(rv.is_err());
|
assert!(rv.is_err());
|
||||||
@@ -93,6 +92,7 @@ fn test_schema() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_program() {
|
fn test_program() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
fn tester(scope: Scope, view: View) {
|
fn tester(scope: Scope, view: View) {
|
||||||
// build program
|
// build program
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ static VERB: LazyLock<ShellVerb> = LazyLock::new(|| {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_app_paths_key() {
|
fn test_app_paths_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe";
|
static APP_PATH: &str = r"C:\Program Files\Passoc\passoc.exe";
|
||||||
static APP_DIR: &str = r"C:\Program Files\Passoc";
|
static APP_DIR: &str = r"C:\Program Files\Passoc";
|
||||||
@@ -75,6 +76,7 @@ fn test_app_paths_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_applications_key() {
|
fn test_applications_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static FRIENDLY_APP_NAME: LazyLock<StrResVariant> =
|
static FRIENDLY_APP_NAME: LazyLock<StrResVariant> =
|
||||||
LazyLock::new(|| "Passoc Application".into());
|
LazyLock::new(|| "Passoc Application".into());
|
||||||
@@ -177,6 +179,7 @@ fn test_applications_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ext_key() {
|
fn test_ext_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
fn tester(scope: Scope, view: View) {
|
fn tester(scope: Scope, view: View) {
|
||||||
let mut key = ExtKey::new(EXT.clone());
|
let mut key = ExtKey::new(EXT.clone());
|
||||||
@@ -246,6 +249,7 @@ fn test_ext_key() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_prog_id_key() {
|
fn test_prog_id_key() {
|
||||||
common::check_sandbox();
|
common::check_sandbox();
|
||||||
|
common::check_privilege();
|
||||||
|
|
||||||
static LEGACY_NAME: LazyLock<StrResVariant> = LazyLock::new(|| "Passoc Pacfg File".into());
|
static LEGACY_NAME: LazyLock<StrResVariant> = LazyLock::new(|| "Passoc Pacfg File".into());
|
||||||
static FRIENDLY_TYPE_NAME: LazyLock<StrResVariant> =
|
static FRIENDLY_TYPE_NAME: LazyLock<StrResVariant> =
|
||||||
|
|||||||
Reference in New Issue
Block a user