Skip to content

Commit

Permalink
lnk parse
Browse files Browse the repository at this point in the history
  • Loading branch information
SOVLOOKUP committed Oct 19, 2023
1 parent 662c7b2 commit f08a821
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 56 deletions.
5 changes: 2 additions & 3 deletions addon/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ export function getClipboardContent(): ClipBoardContentJson | null
export function onInputEvent(callback: (event: string) => void): void
export function grabInputEvent(callback: (event: string) => boolean): void
export function exeLookBase64(fileName: string): string
export function parseLnk(path: string): string
export function parseLnkFallback(path: string): LnkData
export function parseLnk(path: string): LnkData
export function sendKeyboardSimulation(cmd: string): void
export const enum MouseBtn {
Left = 0,
Expand Down Expand Up @@ -48,7 +47,7 @@ export class ShorCutImg {
}
export class LnkData {
nameString?: string
relativePath?: string
fullPath?: string
workingDir?: string
iconLocation?: string
}
3 changes: 1 addition & 2 deletions addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { getClipboardContent, onInputEvent, grabInputEvent, ShorCutImg, exeLookBase64, parseLnk, LnkData, parseLnkFallback, sendKeyboardSimulation, MouseBtn, MouseAction, sendMouseSimulation } = nativeBinding
const { getClipboardContent, onInputEvent, grabInputEvent, ShorCutImg, exeLookBase64, parseLnk, LnkData, sendKeyboardSimulation, MouseBtn, MouseAction, sendMouseSimulation } = nativeBinding

module.exports.getClipboardContent = getClipboardContent
module.exports.onInputEvent = onInputEvent
Expand All @@ -261,7 +261,6 @@ module.exports.ShorCutImg = ShorCutImg
module.exports.exeLookBase64 = exeLookBase64
module.exports.parseLnk = parseLnk
module.exports.LnkData = LnkData
module.exports.parseLnkFallback = parseLnkFallback
module.exports.sendKeyboardSimulation = sendKeyboardSimulation
module.exports.MouseBtn = MouseBtn
module.exports.MouseAction = MouseAction
Expand Down
1 change: 1 addition & 0 deletions addon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![deny(clippy::all)]
#![feature(absolute_path)]
#[macro_use]
extern crate napi_derive;

Expand Down
74 changes: 50 additions & 24 deletions addon/src/shotcut/mod.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,69 @@
use lnk_parser::LNKParser;
use napi::Result;
use std::path::PathBuf;
use std::path::{absolute, PathBuf};
pub mod exelook;

#[napi]
pub fn parse_lnk(path: String) -> Result<String> {
pub fn parse_lnk(path: String) -> Result<LnkData> {
let lnk_file = LNKParser::from_path(&path);
match lnk_file {
Ok(f) => Ok(serde_json::to_string(&f).unwrap()),
Err(e) => Err(napi::Error::from_reason(e.to_string())),
Ok(f) => {
let name_string = f.get_name_string().as_ref().map(|f| f.to_string());
let full_path = f
.get_target_full_path()
.as_ref()
.map(|f| {
if f.starts_with("MY_COMPUTER\\") {
Some(f.to_string().replace("MY_COMPUTER\\", ""))
} else {
Some(f.to_string())
}
})
.map_or(None, |f| f);
let working_dir = f.get_working_dir().as_ref().map(|f| f.to_string());
let icon_location = f.get_icon_location().as_ref().map(|f| f.to_string());

Ok(LnkData {
name_string,
full_path,
working_dir,
icon_location,
})
}
Err(_) => {
let lnk_path = std::path::Path::new(&path);
let lnk = parselnk::Lnk::try_from(lnk_path);
match lnk {
Ok(l) => {
let s = absolute(
PathBuf::from(lnk_path)
.parent()
.unwrap()
.join(l.string_data.relative_path.unwrap()),
)
.map_or(None, |f| Some(f));

Ok(LnkData {
name_string: l.string_data.name_string,
full_path: convert(s),
working_dir: convert(l.string_data.working_dir),
icon_location: convert(l.string_data.icon_location),
})
}
Err(e) => Err(napi::Error::from_reason(e.to_string())),
}
}
}
}

#[napi]
pub struct LnkData {
pub name_string: Option<String>,
pub relative_path: Option<String>,
pub full_path: Option<String>,
pub working_dir: Option<String>,
pub icon_location: Option<String>,
}

fn convert(p: Option<PathBuf>) -> Option<String> {
match p {
Some(p) => Some(p.to_str().unwrap().to_string()),
None => None,
}
}

#[napi]
pub fn parse_lnk_fallback(path: String) -> Result<LnkData> {
let lnk_path = std::path::Path::new(&path);
let lnk = parselnk::Lnk::try_from(lnk_path);
match lnk {
Ok(l) => Ok(LnkData {
name_string: l.string_data.name_string,
relative_path: convert(l.string_data.relative_path),
working_dir: convert(l.string_data.working_dir),
icon_location: convert(l.string_data.icon_location),
}),
Err(e) => Err(napi::Error::from_reason(e.to_string())),
}
p.map(|f| f.to_string_lossy().to_string())
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rubick-native",
"version": "0.0.14",
"version": "0.0.15-beta",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.js",
Expand Down
33 changes: 10 additions & 23 deletions src/sysapp/windows.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,22 @@
import { join, parse } from "path";
import { homedir } from "os"
import { fdir } from "fdir";
import { parseLnkFallback, parseLnk } from "../../addon"
import { parseLnk } from "../../addon"
import { CallBack } from ".";

export const shortcutWin = async (callback: CallBack, extraPath: string[] = []) => {
const hdir = homedir()
const f = new fdir().glob("./**/*.lnk").withFullPaths()
.filter((t) => {
const { name, dir } = parse(t)
try {
const data = parseLnk(t)
const d = JSON.parse(data)
callback({
name,
description: d.name_string ?? null,
execPath: d.target_full_path,
shortCutPath: t,
workingDir: d.working_dir ?? null,
})
} catch {
const d = parseLnkFallback(t)
const execPath = join(dir, d.relativePath ?? '')
callback({
name,
description: d.nameString ?? null,
execPath,
shortCutPath: t,
workingDir: d.workingDir ?? null,
})
}
const { name } = parse(t)
const d = parseLnk(t)
callback({
name,
description: d.nameString,
execPath: d.fullPath,
shortCutPath: t,
workingDir: d.workingDir
})
return true
})
const defaultPaths = [
Expand Down
8 changes: 5 additions & 3 deletions test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { existsSync } from "fs";
import { getSystemApp } from "./src"

console.time("1")
getSystemApp((e) => {
console.log(e);

await getSystemApp((e) => {
if (!existsSync(e.execPath)) {
console.log(e);
}
})
console.timeEnd("1")

0 comments on commit f08a821

Please sign in to comment.