use dotscope::project::ProjectLoader;
use std::env;
fn main() -> dotscope::Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!(
"Usage: {} <assembly-path> [--search-path <path>] [--search-path <path2>] ...",
args[0]
);
eprintln!();
eprintln!("Options:");
eprintln!(" --search-path <path> Add a directory to search for dependencies");
eprintln!(" (can be specified multiple times)");
eprintln!();
eprintln!("Examples:");
eprintln!(" {} MyApp.exe", args[0]);
eprintln!(" {} MyApp.exe --search-path /usr/lib/mono/4.5", args[0]);
eprintln!(
" {} tests/samples/crafted_2.exe --search-path tests/samples/mono_4.8",
args[0]
);
std::process::exit(1);
}
let assembly_path = &args[1];
let mut search_paths: Vec<String> = Vec::new();
let mut i = 2;
while i < args.len() {
if args[i] == "--search-path" && i + 1 < args.len() {
search_paths.push(args[i + 1].clone());
i += 2;
} else {
i += 1;
}
}
println!("=== dotscope Project Loader Example ===\n");
println!("Loading assembly: {}", assembly_path);
let mut loader = ProjectLoader::new().primary_file(assembly_path)?;
if !search_paths.is_empty() {
println!("Search paths:");
for path in &search_paths {
println!(" - {}", path);
loader = loader.with_search_path(path)?;
}
loader = loader.auto_discover(true);
} else {
if let Some(parent) = std::path::Path::new(assembly_path).parent() {
if parent.exists() && parent.is_dir() {
loader = loader.with_search_path(parent)?.auto_discover(true);
println!("Search path: {} (auto)", parent.display());
}
}
}
println!();
let result = loader.build()?;
println!("=== Loading Results ===\n");
println!(
"Assemblies loaded: {} successful, {} failed",
result.success_count(),
result.failure_count()
);
if !result.loaded_assemblies.is_empty() {
println!("\nLoaded assemblies:");
for identity in &result.loaded_assemblies {
println!(" - {} v{}", identity.name, identity.version);
}
}
if !result.missing_dependencies.is_empty() {
println!("\nMissing dependencies:");
for dep in &result.missing_dependencies {
println!(" - {}", dep);
}
}
if !result.version_mismatches.is_empty() {
println!("\nVersion mismatches:");
for mismatch in &result.version_mismatches {
println!(
" - {} (required: {}, found: {})",
mismatch.required.name, mismatch.required.version, mismatch.actual.version
);
}
}
if !result.failed_loads.is_empty() {
println!("\nFailed loads:");
for (name, error) in &result.failed_loads {
println!(" - {}: {}", name, error);
}
}
let project = &result.project;
println!("\n=== Project Analysis ===\n");
println!("Total assemblies in project: {}", project.assembly_count());
if let Some(primary) = project.get_primary() {
println!("\nPrimary Assembly Details:");
if let Some(assembly_info) = primary.assembly() {
println!(" Name: {}", assembly_info.name);
println!(
" Version: {}.{}.{}.{}",
assembly_info.major_version,
assembly_info.minor_version,
assembly_info.build_number,
assembly_info.revision_number
);
}
println!(" Types: {}", primary.types().len());
println!(" Methods: {}", primary.methods().len());
let types = primary.types();
if !types.is_empty() {
println!("\n Sample types (up to 10):");
for entry in types.iter().take(10) {
let ciltype = entry.value();
println!(" - {} ({:?})", ciltype.fullname(), ciltype.flavor());
}
if types.len() > 10 {
println!(" ... and {} more", types.len() - 10);
}
}
}
println!("\n=== All Assemblies Summary ===\n");
for (identity, assembly) in project.iter() {
println!(
"{}: {} types, {} methods",
identity.name,
assembly.types().len(),
assembly.methods().len()
);
}
println!("\n=== Cross-Assembly Type Lookup ===\n");
let types_to_find = ["System.Object", "System.String", "System.Int32"];
for type_name in &types_to_find {
match project.get_type_by_name(type_name) {
Some(ciltype) => {
println!("Found {}: {} methods", type_name, ciltype.methods.count());
}
None => {
println!("{}: not found in loaded assemblies", type_name);
}
}
}
println!("\n=== Type Definition Search ===\n");
let definitions = project.find_type_definitions("Object");
if definitions.is_empty() {
println!("No types matching 'Object' found");
} else {
println!("Types matching 'Object':");
for (identity, ciltype) in definitions.iter().take(5) {
println!(" - {} in {}", ciltype.fullname(), identity.name);
}
if definitions.len() > 5 {
println!(" ... and {} more", definitions.len() - 5);
}
}
println!("\n=== Complete ===");
Ok(())
}