i2pd-launch 0.5.0-beta.4

Launches i2pd with clean state
#[cfg(windows)]
#[allow(unsafe_code)]
pub fn background_detached(exe: &std::path::Path) -> std::io::Result<()> {
   use std::ffi::OsString;
   use std::os::windows::ffi::OsStrExt;
   use windows_sys::Win32::Foundation::BOOL;
   use windows_sys::Win32::System::Threading::{
      CreateProcessW, CREATE_NEW_PROCESS_GROUP, DETACHED_PROCESS, PROCESS_INFORMATION, STARTUPINFOW,
   };

   // Sestavení příkazového řádku: "C:\path\to\exe.exe" -w -d
   let cmdline: Vec<u16> = OsString::from(format!("\"{}\" -w -d", exe.display()))
      .encode_wide()
      .chain(Some(0))
      .collect();

   let app_name: Vec<u16> = exe.as_os_str().encode_wide().chain(Some(0)).collect();

   let mut si: STARTUPINFOW = unsafe { std::mem::zeroed() };
   si.cb = std::mem::size_of::<STARTUPINFOW>() as u32;

   let mut pi: PROCESS_INFORMATION = unsafe { std::mem::zeroed() };

   let ok: BOOL = unsafe {
      CreateProcessW(
         app_name.as_ptr(),                           // lpApplicationName
         cmdline.as_ptr() as *mut u16,                // lpCommandLine (mutovatelný!)
         std::ptr::null_mut(),                        // lpProcessAttributes
         std::ptr::null_mut(),                        // lpThreadAttributes
         0,                                           // bInheritHandles = FALSE
         DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP, // dwCreationFlags
         std::ptr::null_mut(),                        // lpEnvironment (zdědí)
         std::ptr::null_mut(),                        // lpCurrentDirectory (zdědí)
         &si,
         &mut pi,
      )
   };

   if ok == 0 {
      return Err(std::io::Error::last_os_error());
   }

   // Okamžitě zavřít handle nového procesu — nepotřebujeme čekat
   unsafe {
      windows_sys::Win32::Foundation::CloseHandle(pi.hProcess);
      windows_sys::Win32::Foundation::CloseHandle(pi.hThread);
   }

   Ok(())
}