doe 1.1.90

doe is a powerful Rust crate designed to enhance development workflow by providing an extensive collection of useful macros and utility functions. It not only simplifies common tasks but also offers convenient features for clipboard management,robust cryptographic functions,keyboard input, and mouse interaction.
Documentation
//! Process enumeration and termination helpers (feature `process`).
//!
//! Provides cross-platform access to the running process list (name + pid)
//! and the ability to kill a process by name or pid.

// The inner `pub mod process` mirrors the convention used by every other
// module in this crate (feature-gated body + `pub use process::*` re-export),
// so the public path stays `doe::process::*`. Allow the clippy lint rather
// than reshape the public API.
#![allow(clippy::module_inception)]

#[cfg(feature = "process")]
pub mod process {
    //! Cross-platform process enumeration (`get_all_process_name_and_pid`) and
    //! termination helpers (`kill_process_by_*`).
    /// A struct representing information about a process, including its PID and name.
    #[derive(Debug, Clone, Default)]
    pub struct ProcessInfo {
        /// The process ID.
        pub pid: u64,
        /// The process name.
        pub name: String,
    }

    /// todo: implement
    #[allow(warnings)]
    #[cfg(target_os = "macos")]
    pub fn get_all_process_name_and_pid() -> Vec<ProcessInfo> {
        use cocoa::appkit;
        todo!()
    }
    /// Retrieves information about all running processes on a Windows system.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// use doe::process::*;
    /// let processes: Vec<ProcessInfo> = get_all_process_name_and_pid();
    /// for process in processes {
    ///     println!("Process ID: {}, Name: {}", process.pid, process.name);
    /// }
    /// ```
    #[cfg(target_os = "windows")]
    pub fn get_all_process_name_and_pid() -> Vec<ProcessInfo> {
        use std::mem;
        use winapi::shared::minwindef::TRUE;
        use winapi::um::tlhelp32::{
            Process32FirstW, Process32NextW, PROCESSENTRY32W, TH32CS_SNAPPROCESS,
        };

        let mut res = vec![];
        unsafe {
            let snapshot = winapi::um::tlhelp32::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
            if snapshot == winapi::um::handleapi::INVALID_HANDLE_VALUE {
                panic!("Failed to create snapshot");
            }

            let mut process_entry: PROCESSENTRY32W = mem::zeroed();
            process_entry.dwSize = mem::size_of::<PROCESSENTRY32W>() as u32;

            if Process32FirstW(snapshot, &mut process_entry) == TRUE {
                loop {
                    res.push(ProcessInfo {
                        pid: process_entry.th32ProcessID as u64,
                        name: String::from_utf16_lossy(&process_entry.szExeFile)
                            .trim()
                            .to_string()
                            .replace("\0", ""),
                    });
                    // println!("Process ID: {}, Name: {}", process_entry.th32ProcessID, String::from_utf16_lossy(&process_entry.szExeFile));
                    if Process32NextW(snapshot, &mut process_entry) != TRUE {
                        break;
                    }
                }
            }
            winapi::um::handleapi::CloseHandle(snapshot);
        }
        res
    }
    #[cfg(target_os = "windows")]
    /// Attempts to terminate a process with the specified PID on a Windows system.
    ///
    /// # Arguments
    ///
    /// * `pid` - The process ID of the process to be terminated.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// use doe::process::*;
    /// kill_process_by_pid(pid_to_kill);
    /// ```
    pub fn kill_process_by_pid(pid: u64) {
        use winapi::shared::minwindef::{DWORD, FALSE};
        use winapi::um::handleapi::CloseHandle;
        use winapi::um::processthreadsapi::{OpenProcess, TerminateProcess};
        use winapi::um::winnt::PROCESS_TERMINATE;
        unsafe {
            let process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, pid as DWORD);
            if process_handle.is_null() {
                eprintln!("Failed to open process with PID: {}", pid);
                return;
            }
            if TerminateProcess(process_handle, 0) == FALSE {
                eprintln!("Failed to terminate process with PID: {}", pid);
            }
            CloseHandle(process_handle);
        }
    }
}

#[cfg(feature = "process")]
pub use process::*;