This commit is contained in:
Timon
2026-05-08 15:28:19 +00:00
parent 6cd8b2d6c2
commit a4885a5f0c
4 changed files with 71 additions and 1 deletions

14
Cargo.lock generated
View File

@@ -2138,6 +2138,7 @@ name = "graphite-desktop-platform-win"
version = "0.0.0"
dependencies = [
"graphite-desktop",
"windows-registry 0.6.1",
"winres",
]
@@ -2439,7 +2440,7 @@ dependencies = [
"tokio",
"tower-service",
"tracing",
"windows-registry",
"windows-registry 0.5.3",
]
[[package]]
@@ -6848,6 +6849,17 @@ dependencies = [
"windows-strings 0.4.2",
]
[[package]]
name = "windows-registry"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720"
dependencies = [
"windows-link 0.2.1",
"windows-result 0.4.1",
"windows-strings 0.5.1",
]
[[package]]
name = "windows-result"
version = "0.2.0"

View File

@@ -15,5 +15,8 @@ path = "src/main.rs"
[dependencies]
graphite-desktop = { path = "../.." }
[target.'cfg(target_os = "windows")'.dependencies]
windows-registry = "0.6"
[target.'cfg(target_os = "windows")'.build-dependencies]
winres = "0.1"

View File

@@ -0,0 +1,48 @@
use std::env;
use std::error::Error;
use windows_registry::CURRENT_USER;
const PROG_ID: &str = "Graphite.Document";
const EXECUTABLE_NAME: &str = "Graphite.exe";
const APP_FRIENDLY_NAME: &str = "Graphite";
const DOCUMENT_FRIENDLY_NAME: &str = "Graphite Document";
const MIME_TYPE: &str = "application/graphite+json";
const FILE_EXTENSION: &str = ".graphite";
const SUPPORTED_EXTENSIONS: &[&str] = &[FILE_EXTENSION, ".svg", ".png", ".jpg", ".jpeg"];
pub fn register() {
if let Err(e) = register_inner() {
eprintln!("Failed to register file associations: {e}");
}
}
fn register_inner() -> Result<(), Box<dyn Error>> {
let exe = env::current_exe()?;
let exe_string = exe.to_string_lossy();
let open_command = format!("\"{exe_string}\" \"%1\"");
let icon_value = format!("{exe_string},0");
let prog_id = CURRENT_USER.create(format!("Software\\Classes\\{PROG_ID}"))?;
prog_id.set_string("", DOCUMENT_FRIENDLY_NAME)?;
let prog_id_icon = CURRENT_USER.create(format!("Software\\Classes\\{PROG_ID}\\DefaultIcon"))?;
prog_id_icon.set_string("", &icon_value)?;
let prog_id_command = CURRENT_USER.create(format!("Software\\Classes\\{PROG_ID}\\shell\\open\\command"))?;
prog_id_command.set_string("", &open_command)?;
let app_base = format!("Software\\Classes\\Applications\\{EXECUTABLE_NAME}");
let app = CURRENT_USER.create(&app_base)?;
app.set_string("FriendlyAppName", APP_FRIENDLY_NAME)?;
let app_command = CURRENT_USER.create(format!("{app_base}\\shell\\open\\command"))?;
app_command.set_string("", &open_command)?;
let supported = CURRENT_USER.create(format!("{app_base}\\SupportedTypes"))?;
for extension in SUPPORTED_EXTENSIONS {
supported.set_string(extension, "")?;
}
let extension = CURRENT_USER.create(format!("Software\\Classes\\{FILE_EXTENSION}"))?;
extension.set_string("", PROG_ID)?;
extension.set_string("Content Type", MIME_TYPE)?;
Ok(())
}

View File

@@ -1,4 +1,11 @@
#![windows_subsystem = "windows"]
#[cfg(target_os = "windows")]
mod file_associations;
fn main() {
#[cfg(target_os = "windows")]
file_associations::register();
graphite_desktop::start();
}