diff --git a/src-tauri/resources/verge_tmp.yaml b/src-tauri/resources/verge_tmp.yaml
index 7ba6e28..39b754b 100644
--- a/src-tauri/resources/verge_tmp.yaml
+++ b/src-tauri/resources/verge_tmp.yaml
@@ -3,3 +3,4 @@
 theme_mode: light
 enable_self_startup: false
 enable_system_proxy: false
+system_proxy_bypass: localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>
diff --git a/src-tauri/src/cmds/some.rs b/src-tauri/src/cmds/some.rs
index 49ff1c2..cd76bef 100644
--- a/src-tauri/src/cmds/some.rs
+++ b/src-tauri/src/cmds/some.rs
@@ -7,7 +7,7 @@ use crate::{
   utils::{
     clash::run_clash_bin,
     config::{read_clash, save_clash, save_verge},
-    sysopt::{get_proxy_config, set_proxy_config, SysProxyConfig},
+    sysopt::{get_proxy_config, set_proxy_config, SysProxyConfig, DEFAULT_BYPASS},
   },
 };
 use serde_yaml::Mapping;
@@ -53,12 +53,21 @@ pub fn patch_clash_config(payload: Mapping) -> Result<(), String> {
 /// set the system proxy
 /// Tips: only support windows now
 #[tauri::command]
-pub fn set_sys_proxy(enable: bool, clash_info: State<'_, ClashInfoState>) -> Result<(), String> {
+pub fn set_sys_proxy(
+  enable: bool,
+  clash_info: State<'_, ClashInfoState>,
+  verge_lock: State<'_, VergeConfLock>,
+) -> Result<(), String> {
   let clash_info = match clash_info.0.lock() {
     Ok(arc) => arc.clone(),
     _ => return Err(format!("can not get clash info")),
   };
 
+  let verge_info = match verge_lock.0.lock() {
+    Ok(arc) => arc.clone(),
+    _ => return Err(format!("can not get verge info")),
+  };
+
   let port = match clash_info.controller {
     Some(ctrl) => ctrl.port,
     None => None,
@@ -70,9 +79,9 @@ pub fn set_sys_proxy(enable: bool, clash_info: State<'_, ClashInfoState>) -> Res
 
   let config = if enable {
     let server = format!("127.0.0.1:{}", port.unwrap());
-    // todo
-    let bypass = String::from("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>");
-
+    let bypass = verge_info
+      .system_proxy_bypass
+      .unwrap_or(String::from(DEFAULT_BYPASS));
     SysProxyConfig {
       enable,
       server,
@@ -112,6 +121,7 @@ pub fn get_verge_config(verge_lock: State<'_, VergeConfLock>) -> Result<VergeCon
 }
 
 /// patch the verge config
+/// this command only save the config and not responsible for other things
 #[tauri::command]
 pub async fn patch_verge_config(
   payload: VergeConfig,
@@ -136,5 +146,9 @@ pub async fn patch_verge_config(
     verge.enable_system_proxy = payload.enable_system_proxy;
   }
 
+  if payload.system_proxy_bypass.is_some() {
+    verge.system_proxy_bypass = payload.system_proxy_bypass;
+  }
+
   save_verge(&verge)
 }
diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs
index 5b7e78e..e322185 100644
--- a/src-tauri/src/config/verge.rs
+++ b/src-tauri/src/config/verge.rs
@@ -11,4 +11,7 @@ pub struct VergeConfig {
 
   /// set system proxy
   pub enable_system_proxy: Option<bool>,
+
+  /// set system proxy bypass
+  pub system_proxy_bypass: Option<String>,
 }
diff --git a/src-tauri/src/events/state.rs b/src-tauri/src/events/state.rs
index 67a91fa..bcdd54e 100644
--- a/src-tauri/src/events/state.rs
+++ b/src-tauri/src/events/state.rs
@@ -1,7 +1,7 @@
 use std::sync::{Arc, Mutex};
 
 use super::emit::ClashInfoPayload;
-use crate::config::VergeConfig;
+use crate::{config::VergeConfig, utils::sysopt::SysProxyConfig};
 
 #[derive(Default)]
 pub struct ClashInfoState(pub Arc<Mutex<ClashInfoPayload>>);
@@ -11,3 +11,6 @@ pub struct ProfileLock(pub Mutex<bool>);
 
 #[derive(Default)]
 pub struct VergeConfLock(pub Arc<Mutex<VergeConfig>>);
+
+#[derive(Default)]
+pub struct SomthingState(pub Arc<Mutex<Option<SysProxyConfig>>>);
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index ff3d3aa..ef465ad 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -12,19 +12,14 @@ mod utils;
 
 use crate::{
   events::state,
-  utils::{
-    clash::put_clash_profile,
-    config::read_verge,
-    server::{check_singleton, embed_server},
-  },
+  utils::{resolve, server},
 };
-use std::sync::{Arc, Mutex};
 use tauri::{
   api, CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem,
 };
 
 fn main() -> std::io::Result<()> {
-  if check_singleton().is_err() {
+  if server::check_singleton().is_err() {
     println!("app exists");
     return Ok(());
   }
@@ -35,44 +30,28 @@ fn main() -> std::io::Result<()> {
     .add_item(CustomMenuItem::new("quit", "退出").accelerator("CmdOrControl+Q"));
 
   tauri::Builder::default()
-    .setup(|app| {
-      // a simple http server
-      embed_server(&app.handle());
-
-      // init app config
-      utils::init::init_app(app.package_info());
-      // run clash sidecar
-      let info = utils::clash::run_clash_bin(&app.handle());
-      // update the profile
-      let info_copy = info.clone();
-      tauri::async_runtime::spawn(async move {
-        match put_clash_profile(&info_copy).await {
-          Ok(_) => {}
-          Err(err) => log::error!("failed to put config for `{}`", err),
-        };
-      });
-
-      app.manage(state::VergeConfLock(Arc::new(Mutex::new(read_verge()))));
-      app.manage(state::ClashInfoState(Arc::new(Mutex::new(info))));
-      app.manage(state::ProfileLock::default());
-      Ok(())
-    })
+    .manage(state::VergeConfLock::default())
+    .manage(state::ClashInfoState::default())
+    .manage(state::SomthingState::default())
+    .manage(state::ProfileLock::default())
+    .setup(|app| Ok(resolve::resolve_setup(app)))
     .system_tray(SystemTray::new().with_menu(menu))
-    .on_system_tray_event(move |app, event| match event {
+    .on_system_tray_event(move |app_handle, event| match event {
       SystemTrayEvent::MenuItemClick { id, .. } => match id.as_str() {
         "open_window" => {
-          let window = app.get_window("main").unwrap();
+          let window = app_handle.get_window("main").unwrap();
           window.show().unwrap();
           window.set_focus().unwrap();
         }
         "quit" => {
           api::process::kill_children();
-          app.exit(0);
+          resolve::resolve_reset(app_handle);
+          app_handle.exit(0);
         }
         _ => {}
       },
       SystemTrayEvent::LeftClick { .. } => {
-        let window = app.get_window("main").unwrap();
+        let window = app_handle.get_window("main").unwrap();
         window.show().unwrap();
         window.set_focus().unwrap();
       }
@@ -104,6 +83,7 @@ fn main() -> std::io::Result<()> {
         api.prevent_exit();
       }
       tauri::Event::Exit => {
+        resolve::resolve_reset(app_handle);
         api::process::kill_children();
       }
       _ => {}
diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs
index 9794a2c..3a09fe4 100644
--- a/src-tauri/src/utils/mod.rs
+++ b/src-tauri/src/utils/mod.rs
@@ -5,5 +5,6 @@ pub mod clash;
 pub mod config;
 pub mod fetch;
 pub mod init;
+pub mod resolve;
 pub mod server;
 pub mod sysopt;
diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs
new file mode 100644
index 0000000..4a13d05
--- /dev/null
+++ b/src-tauri/src/utils/resolve.rs
@@ -0,0 +1,80 @@
+use super::{clash, config, init, server, sysopt};
+use crate::events::state;
+use tauri::{App, AppHandle, Manager};
+
+/// handle something when start app
+pub fn resolve_setup(app: &App) {
+  // setup a simple http server for singleton
+  server::embed_server(&app.handle());
+
+  // init app config
+  init::init_app(app.package_info());
+
+  // run clash sidecar
+  let info = clash::run_clash_bin(&app.handle());
+
+  // update the profile
+  let info_ = info.clone();
+  tauri::async_runtime::spawn(async move {
+    if let Err(err) = clash::put_clash_profile(&info_).await {
+      log::error!("failed to put config for `{}`", err);
+    };
+  });
+
+  // resolve the verge config - enable system proxy
+  let mut original: Option<sysopt::SysProxyConfig> = None;
+  let verge = config::read_verge();
+  let enable = verge.enable_system_proxy.unwrap_or(false);
+
+  if enable && info.controller.is_some() {
+    if let Ok(original_conf) = sysopt::get_proxy_config() {
+      original = Some(original_conf)
+    };
+    let ctl = info.controller.clone().unwrap();
+    if ctl.port.is_some() {
+      let server = format!("127.0.0.1:{}", ctl.port.unwrap());
+      let bypass = verge
+        .system_proxy_bypass
+        .clone()
+        .unwrap_or(String::from(sysopt::DEFAULT_BYPASS));
+      let config = sysopt::SysProxyConfig {
+        enable,
+        server,
+        bypass,
+      };
+      if let Err(err) = sysopt::set_proxy_config(&config) {
+        log::error!("can not set system proxy for `{}`", err);
+      }
+    }
+  }
+  // update state
+  let verge_state = app.state::<state::VergeConfLock>();
+  let mut verge_arc = verge_state.0.lock().unwrap();
+  *verge_arc = verge;
+
+  let clash_state = app.state::<state::ClashInfoState>();
+  let mut clash_arc = clash_state.0.lock().unwrap();
+  *clash_arc = info;
+
+  let some_state = app.state::<state::SomthingState>();
+  let mut some_arc = some_state.0.lock().unwrap();
+  *some_arc = original;
+}
+
+/// reset system proxy
+pub fn resolve_reset(app_handle: &AppHandle) {
+  let state = app_handle.try_state::<state::SomthingState>();
+  if state.is_none() {
+    return;
+  }
+  match state.unwrap().0.lock() {
+    Ok(arc) => {
+      if arc.is_some() {
+        if let Err(err) = sysopt::set_proxy_config(arc.as_ref().unwrap()) {
+          log::error!("failed to reset proxy for `{}`", err);
+        }
+      }
+    }
+    _ => {}
+  };
+}
diff --git a/src-tauri/src/utils/sysopt.rs b/src-tauri/src/utils/sysopt.rs
index 6e487cb..46250e3 100644
--- a/src-tauri/src/utils/sysopt.rs
+++ b/src-tauri/src/utils/sysopt.rs
@@ -1,13 +1,25 @@
 use serde::{Deserialize, Serialize};
 use std::io;
 
-#[derive(Debug, Deserialize, Serialize)]
+#[derive(Debug, Deserialize, Serialize, Clone)]
 pub struct SysProxyConfig {
   pub enable: bool,
   pub server: String,
   pub bypass: String,
 }
 
+impl Default for SysProxyConfig {
+  fn default() -> Self {
+    SysProxyConfig {
+      enable: false,
+      server: String::from(""),
+      bypass: String::from(""),
+    }
+  }
+}
+
+pub static DEFAULT_BYPASS: &str = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*;<local>";
+
 #[cfg(target_os = "windows")]
 mod win {
   use super::*;