Skip to content

Commit

Permalink
compile on windows
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Sep 29, 2024
1 parent 63cd1cb commit bed8a1a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 57 deletions.
1 change: 1 addition & 0 deletions crates/rattler_menuinst/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ fs-err = "2.11.0"
xmltree = "0.11.0"
which = "6.0.3"
shell-words = "1.1.0"
known-folders = "1.2.0"

[target.'cfg(target_os = "windows")'.dependencies]
winapi = "0.3.9"
Expand Down
6 changes: 5 additions & 1 deletion crates/rattler_menuinst/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::path::Path;

use rattler_conda_types::Platform;

#[cfg(target_os = "linux")]
mod linux;
#[cfg(target_os = "macos")]
mod macos;
mod render;
mod schema;
Expand Down Expand Up @@ -55,11 +57,13 @@ pub fn install_menuitems(
let mut linux_item = item.platforms.linux.clone().unwrap();
let base_item = linux_item.base.merge_parent(&item);
linux_item.base = base_item;
#[cfg(target_os = "linux")]
linux::install_menu_item(linux_item, MenuMode::User)?;
} else if item.platforms.osx.is_some() && platform.is_osx() {
let mut macos_item = item.platforms.osx.clone().unwrap();
let base_item = macos_item.base.merge_parent(&item);
macos_item.base = base_item;
#[cfg(target_os = "macos")]
macos::install_menu_item(prefix, macos_item, MenuMode::System)?;
} else if item.platforms.win.is_some() && platform.is_windows() {
// windows::install_menu_item(&item)?;
Expand Down Expand Up @@ -89,7 +93,7 @@ pub mod test {

let prefix = schema_path.parent().unwrap().parent().unwrap();
let prefix = std::fs::canonicalize(prefix).unwrap();
println!("prefix: {:?}", prefix);
println!("prefix: {prefix:?}");
let base_prefix = PathBuf::from("/Users/jaidevd/miniconda3");
let platform = Platform::Linux64;

Expand Down
18 changes: 10 additions & 8 deletions crates/rattler_menuinst/src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::collections::HashMap;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::path::PathBuf;

mod knownfolders;
mod registry;
Expand All @@ -15,9 +11,15 @@ struct Directories {

impl Directories {
pub fn create() -> Directories {
let start_menu_location = dirs::start_menu_dir().unwrap();
let quick_launch_location = dirs::quick_launch_dir().unwrap();
let desktop_location = dirs::desktop_dir().unwrap();
let start_menu_location =
known_folders::get_known_folder_path(known_folders::KnownFolder::StartMenu)
.expect("Failed to get start menu location");
let quick_launch_location =
known_folders::get_known_folder_path(known_folders::KnownFolder::QuickLaunch)
.expect("Failed to get quick launch location");
let desktop_location =
known_folders::get_known_folder_path(known_folders::KnownFolder::Desktop)
.expect("Failed to get desktop location");

Directories {
start_menu_location,
Expand Down
34 changes: 5 additions & 29 deletions crates/rattler_menuinst/src/windows/knownfolders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct Folders {
user_folders: HashMap<String, KnownFolder>,
}

#[derive(Clone, Copy)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum UserHandle {
Current,
Common,
Expand Down Expand Up @@ -59,15 +59,15 @@ impl Folders {
};

if let Some(folder) = preferred_folders.get(key) {
if let Some(path) = get_known_folder_path(folder) {
if let Some(path) = get_known_folder_path(*folder) {
return Ok(path);
}
}

// Implement fallback for user documents
if preferred_mode == UserHandle::Current && key == "documents" {
if let Some(profile_folder) = preferred_folders.get("profile") {
if let Some(profile_path) = get_known_folder_path(profile_folder) {
if let Some(profile_path) = get_known_folder_path(*profile_folder) {
let documents_path = profile_path.join("Documents");
if documents_path.is_dir() {
return Ok(documents_path);
Expand All @@ -78,7 +78,7 @@ impl Folders {

if check_other_mode {
if let Some(folder) = other_folders.get(key) {
if let Some(path) = get_known_folder_path(folder) {
if let Some(path) = get_known_folder_path(*folder) {
return Ok(path);
}
}
Expand All @@ -87,7 +87,7 @@ impl Folders {
Err(FolderError::PathNotFound)
}

pub fn verify_path<P: AsRef<Path>>(&self, path: P) -> Result<PathBuf, FolderError> {
pub fn verify_path<P: AsRef<Path>>(path: P) -> Result<PathBuf, FolderError> {
let path = path.as_ref();
if path.exists() && path.is_dir() {
Ok(path.to_path_buf())
Expand All @@ -96,27 +96,3 @@ impl Folders {
}
}
}

fn main() {
let folders = Folders::new();

let test_folders = vec![
("desktop", UserHandle::Current),
("documents", UserHandle::Current),
("start", UserHandle::Common),
("profile", UserHandle::Common),
];

for (folder, handle) in test_folders {
match folders.get_folder_path(folder, handle) {
Ok(path) => {
tracing::info!("{} path for {:?}: {:?}", folder, handle, path);
match folders.verify_path(&path) {
Ok(_) => println!(" Path verified successfully"),
Err(e) => println!(" Path verification failed: {:?}", e),
}
}
Err(e) => tracing::error!("Error getting {} path for {:?}: {:?}", folder, handle, e),
}
}
}
45 changes: 26 additions & 19 deletions crates/rattler_menuinst/src/windows/registry.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use anyhow::{Context, Result};
use winreg::enums::*;
use winreg::enums::{HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS};
use winreg::RegKey;

pub fn register_file_extension(
Expand All @@ -8,7 +7,7 @@ pub fn register_file_extension(
command: &str,
icon: Option<&str>,
mode: &str,
) -> Result<()> {
) -> Result<(), std::io::Error> {
let hkey = if mode == "system" {
HKEY_LOCAL_MACHINE
} else {
Expand All @@ -19,34 +18,38 @@ pub fn register_file_extension(
RegKey::predef(hkey).open_subkey_with_flags("Software\\Classes", KEY_ALL_ACCESS)?;

// Associate extension with handler
let ext_key = classes.create_subkey(&format!("{}\\OpenWithProgids", extension))?;
let ext_key = classes.create_subkey(format!("{extension}\\OpenWithProgids"))?;
ext_key.0.set_value(identifier, &"")?;
tracing::debug!("Created registry entry for extension '{}'", extension);

// Register the handler
let handler_desc = format!("{} {} handler", extension, identifier);
let handler_desc = format!("{extension} {identifier} handler");
classes
.create_subkey(identifier)?
.0
.set_value("", &handler_desc)?;
tracing::debug!("Created registry entry for handler '{}'", identifier);
tracing::debug!("Created registry entry for handler '{identifier}'");

// Set the 'open' command
let command_key = classes.create_subkey(&format!("{}\\shell\\open\\command", identifier))?;
let command_key = classes.create_subkey(format!("{identifier}\\shell\\open\\command"))?;
command_key.0.set_value("", &command)?;
debug!("Created registry entry for command '{}'", command);
tracing::debug!("Created registry entry for command '{command}'");

// Set icon if provided
if let Some(icon_path) = icon {
let icon_key = classes.create_subkey(identifier)?;
icon_key.0.set_value("DefaultIcon", &icon_path)?;
tracing::debug!("Created registry entry for icon '{}'", icon_path);
tracing::debug!("Created registry entry for icon '{icon_path}'");
}

Ok(())
}

pub fn unregister_file_extension(extension: &str, identifier: &str, mode: &str) -> Result<()> {
pub fn unregister_file_extension(
extension: &str,
identifier: &str,
mode: &str,
) -> Result<(), std::io::Error> {
let hkey = if mode == "system" {
HKEY_LOCAL_MACHINE
} else {
Expand All @@ -61,22 +64,23 @@ pub fn unregister_file_extension(extension: &str, identifier: &str, mode: &str)

// Remove the association in OpenWithProgids
let ext_key =
classes.open_subkey_with_flags(&format!("{}\\OpenWithProgids", extension), KEY_ALL_ACCESS);
classes.open_subkey_with_flags(format!("{extension}\\OpenWithProgids"), KEY_ALL_ACCESS);

match ext_key {
Ok(key) => {
if key.get_value::<String, _>(identifier).is_err() {
debug!(
tracing::debug!(
"Handler '{}' is not associated with extension '{}'",
identifier, extension
identifier,
extension
);
} else {
key.delete_value(identifier)?;
}
}
Err(e) => {
tracing::error!("Could not check key '{}' for deletion: {}", extension, e);
return Err(e.into());
return Err(e);
}
}

Expand All @@ -89,20 +93,19 @@ pub fn register_url_protocol(
identifier: Option<&str>,
icon: Option<&str>,
mode: &str,
) -> Result<()> {
) -> Result<(), std::io::Error> {
let key = if mode == "system" {
RegKey::predef(HKEY_CLASSES_ROOT).create_subkey(protocol)?
} else {
RegKey::predef(HKEY_CURRENT_USER)
.create_subkey(&format!("Software\\Classes\\{}", protocol))?
RegKey::predef(HKEY_CURRENT_USER).create_subkey(format!("Software\\Classes\\{protocol}"))?
};

key.0
.set_value("", &format!("URL:{}", protocol.to_uppercase()))?;
key.0.set_value("URL Protocol", &"")?;

let command_key = key.0.create_subkey(r"shell\open\command")?;
command_key.set_value("", &command)?;
command_key.0.set_value("", &command)?;

if let Some(icon_path) = icon {
key.0.set_value("DefaultIcon", &icon_path)?;
Expand All @@ -115,7 +118,11 @@ pub fn register_url_protocol(
Ok(())
}

pub fn unregister_url_protocol(protocol: &str, identifier: Option<&str>, mode: &str) -> Result<()> {
pub fn unregister_url_protocol(
protocol: &str,
identifier: Option<&str>,
mode: &str,
) -> Result<(), std::io::Error> {
let key = if mode == "system" {
RegKey::predef(HKEY_CLASSES_ROOT)
} else {
Expand Down

0 comments on commit bed8a1a

Please sign in to comment.