windows.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. use std::{ffi::OsStr, process::Command};
  2. use crate::{path, usecase::service::*};
  3. use derive_new::new;
  4. use windows_service::{
  5. service::ServiceAccess,
  6. service_manager::{ServiceManager, ServiceManagerAccess},
  7. };
  8. #[derive(Debug, new)]
  9. pub struct WindowsDesktopService {
  10. #[new(value = "DesktopServiceState::Stopped")]
  11. pub state: DesktopServiceState,
  12. }
  13. impl IDesktopService for WindowsDesktopService {
  14. fn start(&mut self) {
  15. call(
  16. [
  17. "echo.",
  18. "%nssm% stop hbbr",
  19. "%nssm% remove hbbr confirm",
  20. "%nssm% stop hbbs",
  21. "%nssm% remove hbbs confirm",
  22. "mkdir logs",
  23. "echo.",
  24. "service\\run.cmd hbbs",
  25. "echo.",
  26. "service\\run.cmd hbbr",
  27. "echo.",
  28. "@ping 127.1 -n 3 >nul",
  29. ]
  30. .join(" & "),
  31. );
  32. self.check();
  33. }
  34. fn stop(&mut self) {
  35. call(
  36. [
  37. "echo.",
  38. "%nssm% stop hbbr",
  39. "%nssm% remove hbbr confirm",
  40. "echo.",
  41. "%nssm% stop hbbs",
  42. "%nssm% remove hbbs confirm",
  43. "echo.",
  44. "@ping 127.1 -n 3 >nul",
  45. ]
  46. .join(" & "),
  47. );
  48. self.check();
  49. }
  50. fn restart(&mut self) {
  51. nssm(["restart", "hbbs"].map(|x| x.to_owned()));
  52. nssm(["restart", "hbbr"].map(|x| x.to_owned()));
  53. self.check();
  54. }
  55. fn pause(&mut self) {
  56. call(
  57. [
  58. "echo.",
  59. "%nssm% stop hbbr",
  60. "echo.",
  61. "%nssm% stop hbbs",
  62. "echo.",
  63. "@ping 127.1 -n 3 >nul",
  64. ]
  65. .join(" & "),
  66. );
  67. self.check();
  68. }
  69. fn check(&mut self) -> DesktopServiceState {
  70. self.state = match service_status("hbbs").as_str() {
  71. "Running" => DesktopServiceState::Started,
  72. // "Stopped" => DeskServerServiceState::Paused,
  73. _ => DesktopServiceState::Stopped,
  74. };
  75. self.state.to_owned()
  76. }
  77. }
  78. fn call(cmd: String) {
  79. Command::new("cmd")
  80. .current_dir(&path())
  81. .env("nssm", "service\\nssm.exe")
  82. .arg("/c")
  83. .arg("start")
  84. .arg("cmd")
  85. .arg("/c")
  86. .arg(cmd)
  87. .output()
  88. .expect("cmd exec error!");
  89. }
  90. fn exec<I, S>(program: S, args: I) -> String
  91. where
  92. I: IntoIterator<Item = S>,
  93. S: AsRef<OsStr>,
  94. {
  95. match Command::new(program).args(args).output() {
  96. Ok(out) => String::from_utf8(out.stdout).unwrap_or("".to_owned()),
  97. Err(e) => e.to_string(),
  98. }
  99. }
  100. fn nssm<I>(args: I) -> String
  101. where
  102. I: IntoIterator<Item = String>,
  103. {
  104. exec(
  105. format!("{}\\service\\nssm.exe", path().to_str().unwrap_or_default()),
  106. args,
  107. )
  108. .replace("\0", "")
  109. .trim()
  110. .to_owned()
  111. }
  112. fn service_status(name: &str) -> String {
  113. match ServiceManager::local_computer(None::<&OsStr>, ServiceManagerAccess::CONNECT) {
  114. Ok(manager) => match manager.open_service(name, ServiceAccess::QUERY_STATUS) {
  115. Ok(service) => match service.query_status() {
  116. Ok(status) => format!("{:?}", status.current_state),
  117. Err(e) => e.to_string(),
  118. },
  119. Err(e) => e.to_string(),
  120. },
  121. Err(e) => e.to_string(),
  122. }
  123. }