v1.1
This commit is contained in:
@@ -2,7 +2,6 @@ use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use std::{io, thread};
|
||||
use std::net::ToSocketAddrs;
|
||||
|
||||
use console::style;
|
||||
|
||||
@@ -11,9 +10,10 @@ use windows_service::service::{
|
||||
};
|
||||
use windows_service::service_manager::{ServiceManager, ServiceManagerAccess};
|
||||
use windows_service::Error;
|
||||
use switch::core::{Config, Switch};
|
||||
|
||||
use crate::{BaseArgs, Commands, config, console_out};
|
||||
use crate::config::BaseConfig;
|
||||
use crate::{BaseArgs, Commands, config};
|
||||
use crate::command::{command, CommandEnum};
|
||||
|
||||
pub mod service;
|
||||
mod windows_admin_check;
|
||||
@@ -22,46 +22,6 @@ pub const SERVICE_FLAG: &'static str = "start_switch_service_v1_";
|
||||
pub const SERVICE_NAME: &'static str = "switch-service-v1";
|
||||
pub const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS;
|
||||
|
||||
fn command(cmd: &str) {
|
||||
if let Err(e) = command_(cmd) {
|
||||
println!("{}:{:?}", style("连接服务错误(Connection service error)").red(), e);
|
||||
}
|
||||
}
|
||||
|
||||
fn command_(cmd: &str) -> io::Result<()> {
|
||||
match crate::command::client::CommandClient::new() {
|
||||
Ok(command_client) => {
|
||||
match cmd {
|
||||
"route" => {
|
||||
let list = command_client.route()?;
|
||||
console_out::console_route_table(list);
|
||||
}
|
||||
"list" => {
|
||||
let list = command_client.list()?;
|
||||
console_out::console_device_list(list);
|
||||
}
|
||||
"list-all" => {
|
||||
let list = command_client.list()?;
|
||||
console_out::console_device_list_all(list);
|
||||
}
|
||||
"status" => {
|
||||
let status = command_client.status()?;
|
||||
console_out::console_status(status);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e);
|
||||
println!(
|
||||
"{}:{:?}",
|
||||
style("连接服务错误(Connection service error)").red(), e
|
||||
);
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn admin_check() -> bool {
|
||||
if !windows_admin_check::is_app_elevated() {
|
||||
println!(
|
||||
@@ -97,22 +57,24 @@ pub fn main0(base_args: BaseArgs) {
|
||||
return;
|
||||
}
|
||||
match config::default_config(args) {
|
||||
Ok(base_config) => {
|
||||
Ok(start_config) => {
|
||||
match service_state() {
|
||||
Ok(state) => {
|
||||
if state == ServiceState::Stopped {
|
||||
config::save_config(config::ArgsConfig::new(
|
||||
base_config.token.clone(),
|
||||
base_config.name.clone(),
|
||||
base_config.server.to_string(),
|
||||
base_config.nat_test_server.iter().map(|v| v.to_string()).collect::<Vec<String>>(),
|
||||
base_config.device_id.clone(),
|
||||
))
|
||||
.unwrap();
|
||||
if let Err(e) = config::save_config(config::ArgsConfig::new(
|
||||
start_config.token.clone(),
|
||||
start_config.name.clone(),
|
||||
start_config.server.to_string(),
|
||||
start_config.nat_test_server.iter().map(|v| v.to_string()).collect::<Vec<String>>(),
|
||||
start_config.device_id.clone(),
|
||||
)) {
|
||||
log::error!("{:?}",e);
|
||||
return;
|
||||
}
|
||||
match start() {
|
||||
Ok(_) => {
|
||||
//需要检查启动状态
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
thread::sleep(Duration::from_secs(2));
|
||||
println!("{}", style("启动成功(Start successfully)").green())
|
||||
}
|
||||
Err(e) => {
|
||||
@@ -133,7 +95,38 @@ pub fn main0(base_args: BaseArgs) {
|
||||
"{}",
|
||||
style("服务未安装,在当前进程启动(The service is not installed and started in the current process)").red()
|
||||
);
|
||||
crate::start(base_config.token, base_config.name, base_config.server, base_config.nat_test_server, base_config.device_id);
|
||||
let config = Config::new(
|
||||
start_config.token,
|
||||
start_config.device_id,
|
||||
start_config.name,
|
||||
start_config.server,
|
||||
start_config.nat_test_server,
|
||||
);
|
||||
let mut lock = match config::lock_config() {
|
||||
Ok(lock) => lock,
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
let lock_guard = match lock.try_write() {
|
||||
Ok(lock) => {
|
||||
lock
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{}", style("程序文件被重复打开").red());
|
||||
return;
|
||||
}
|
||||
};
|
||||
match Switch::start(config) {
|
||||
Ok(switch) => {
|
||||
crate::console_listen(&switch);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
}
|
||||
drop(lock_guard);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -154,6 +147,9 @@ pub fn main0(base_args: BaseArgs) {
|
||||
if not_started() {
|
||||
return;
|
||||
}
|
||||
if admin_check() {
|
||||
return;
|
||||
}
|
||||
match stop() {
|
||||
Ok(_) => {
|
||||
println!("{}", style("停止成功(Stopped successfully)").green())
|
||||
@@ -165,6 +161,9 @@ pub fn main0(base_args: BaseArgs) {
|
||||
pause();
|
||||
}
|
||||
Commands::Install(args) => {
|
||||
if admin_check() {
|
||||
return;
|
||||
}
|
||||
let path: PathBuf = args.path.into();
|
||||
if !path.exists() {
|
||||
std::fs::create_dir_all(&path).unwrap();
|
||||
@@ -181,6 +180,9 @@ pub fn main0(base_args: BaseArgs) {
|
||||
pause();
|
||||
}
|
||||
Commands::Uninstall => {
|
||||
if admin_check() {
|
||||
return;
|
||||
}
|
||||
if let Err(e) = uninstall() {
|
||||
log::error!("{:?}", e);
|
||||
} else {
|
||||
@@ -188,28 +190,35 @@ pub fn main0(base_args: BaseArgs) {
|
||||
}
|
||||
pause();
|
||||
}
|
||||
Commands::Config(args) => {}
|
||||
Commands::Config(args) => {
|
||||
if let Err(e) = change(args.auto) {
|
||||
log::error!("{:?}", e);
|
||||
} else {
|
||||
println!("{}", style("配置成功(Config succeeded)").green())
|
||||
}
|
||||
pause();
|
||||
}
|
||||
Commands::Route => {
|
||||
if not_started() {
|
||||
return;
|
||||
}
|
||||
command("route");
|
||||
command(CommandEnum::Route);
|
||||
}
|
||||
Commands::List { all } => {
|
||||
if not_started() {
|
||||
return;
|
||||
}
|
||||
if all {
|
||||
command("list-all");
|
||||
command(CommandEnum::ListAll);
|
||||
} else {
|
||||
command("list");
|
||||
command(CommandEnum::List);
|
||||
}
|
||||
}
|
||||
Commands::Status => {
|
||||
if not_started() {
|
||||
return;
|
||||
}
|
||||
command("status");
|
||||
command(CommandEnum::Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,6 +274,39 @@ fn install(path: PathBuf, auto: bool) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn change(auto: bool) -> Result<(), Error> {
|
||||
let manager_access = ServiceManagerAccess::CONNECT;
|
||||
let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?;
|
||||
|
||||
let service_access = ServiceAccess::QUERY_CONFIG | ServiceAccess::CHANGE_CONFIG;
|
||||
let service = service_manager.open_service(SERVICE_NAME, service_access)?;
|
||||
let config = service.query_config()?;
|
||||
let start_type = if auto {
|
||||
ServiceStartType::AutoStart
|
||||
} else {
|
||||
ServiceStartType::OnDemand
|
||||
};
|
||||
let mut launch_arguments = Vec::new();
|
||||
launch_arguments.push(OsString::from(SERVICE_FLAG));
|
||||
launch_arguments.push(OsString::from(
|
||||
dirs::home_dir().unwrap().join(".switch").to_str().unwrap(),
|
||||
));
|
||||
let service_info = ServiceInfo {
|
||||
name: OsString::from(SERVICE_NAME),
|
||||
display_name: config.display_name,
|
||||
service_type: ServiceType::OWN_PROCESS,
|
||||
start_type,
|
||||
error_control: config.error_control,
|
||||
executable_path: config.executable_path,
|
||||
launch_arguments,
|
||||
dependencies: config.dependencies,
|
||||
account_name: None, // run as System
|
||||
account_password: None,
|
||||
};
|
||||
service.change_config(&service_info)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn uninstall() -> Result<(), Error> {
|
||||
let manager_access = ServiceManagerAccess::CONNECT;
|
||||
let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?;
|
||||
@@ -278,7 +320,6 @@ fn uninstall() -> Result<(), Error> {
|
||||
// Wait for service to stop
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
||||
service.delete()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,16 +2,20 @@
|
||||
// extern crate windows_service;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::net::ToSocketAddrs;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use std::net::ToSocketAddrs;
|
||||
|
||||
use windows_service::{define_windows_service, service_control_handler, service_dispatcher};
|
||||
use windows_service::service::{
|
||||
ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus,
|
||||
};
|
||||
use windows_service::service_control_handler::ServiceControlHandlerResult;
|
||||
use windows_service::{define_windows_service, service_control_handler, service_dispatcher};
|
||||
|
||||
use switch::core::{Config, Switch};
|
||||
|
||||
use crate::config;
|
||||
use crate::windows::config::read_config;
|
||||
|
||||
define_windows_service!(ffi_service_main, switch_service_main);
|
||||
@@ -19,7 +23,7 @@ pub fn switch_service_main(_arguments: Vec<OsString>) {
|
||||
thread::spawn(|| match service_main() {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
log::warn!("{:?}", e);
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -58,10 +62,15 @@ fn service_main() -> windows_service::Result<()> {
|
||||
wait_hint: Duration::default(),
|
||||
process_id: None,
|
||||
})?;
|
||||
if let Ok(switch) = start_switch() {
|
||||
parker.park();
|
||||
if let Err(e) = switch.stop() {
|
||||
log::warn!("switch stop:{:?}",e)
|
||||
match start_switch() {
|
||||
Ok(switch) => {
|
||||
parker.park();
|
||||
if let Err(e) = switch.stop() {
|
||||
log::warn!("switch stop:{:?}",e)
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{:?}",e);
|
||||
}
|
||||
}
|
||||
status_handle.set_service_status(ServiceStatus {
|
||||
@@ -79,7 +88,7 @@ fn start_switch() -> switch::Result<Arc<Switch>> {
|
||||
if let Some(config) = read_config() {
|
||||
let device_id = config.device_id;
|
||||
if device_id.trim().is_empty() {
|
||||
return Err(switch::error::Error::Stop("MAC address error".to_string()));
|
||||
return Err(switch::error::Error::Stop("Device id error".to_string()));
|
||||
}
|
||||
let server_address = if let Some(server_address) = config.server
|
||||
.to_socket_addrs()?
|
||||
@@ -88,11 +97,10 @@ fn start_switch() -> switch::Result<Arc<Switch>> {
|
||||
} else {
|
||||
return Err(switch::error::Error::Stop("server address error".to_string()));
|
||||
};
|
||||
let mut nat_test_server = config.nat_test_server.iter()
|
||||
let nat_test_server = config.nat_test_server.iter()
|
||||
.flat_map(|a| a.to_socket_addrs())
|
||||
.flatten()
|
||||
.collect::<Vec<_>>();
|
||||
;
|
||||
if nat_test_server.is_empty() {
|
||||
return Err(switch::error::Error::Stop("nat test server address error".to_string()));
|
||||
}
|
||||
@@ -108,8 +116,11 @@ fn start_switch() -> switch::Result<Arc<Switch>> {
|
||||
let command_server = crate::command::server::CommandServer::new();
|
||||
let switch1 = switch.clone();
|
||||
thread::spawn(move || {
|
||||
if let Err(e) = config::update_pid(std::process::id()) {
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
if let Err(e) = command_server.start(switch1) {
|
||||
log::warn!("{:?}", e);
|
||||
log::error!("{:?}", e);
|
||||
}
|
||||
});
|
||||
Ok(switch)
|
||||
|
||||
Reference in New Issue
Block a user