windows home支持

This commit is contained in:
fengmengqi 2026-04-02 13:52:26 +08:00
parent 9a86aa6444
commit ef48f58ef1
4 changed files with 66 additions and 10 deletions

View File

@ -197,8 +197,16 @@ fn prepare_command(
return prepared; return prepared;
} }
let mut prepared = Command::new("sh"); let mut prepared = if cfg!(target_os = "windows") && !sh_exists() {
prepared.arg("-lc").arg(command).current_dir(cwd); let mut p = Command::new("cmd");
p.arg("/C").arg(command);
p
} else {
let mut p = Command::new("sh");
p.arg("-lc").arg(command);
p
};
prepared.current_dir(cwd);
if sandbox_status.filesystem_active { if sandbox_status.filesystem_active {
prepared.env("HOME", cwd.join(".sandbox-home")); prepared.env("HOME", cwd.join(".sandbox-home"));
prepared.env("TMPDIR", cwd.join(".sandbox-tmp")); prepared.env("TMPDIR", cwd.join(".sandbox-tmp"));
@ -206,6 +214,21 @@ fn prepare_command(
prepared prepared
} }
fn sh_exists() -> bool {
env::var_os("PATH").is_some_and(|paths| {
env::split_paths(&paths).any(|path| {
#[cfg(windows)]
{
path.join("sh.exe").exists() || path.join("sh.bat").exists() || path.join("sh").exists()
}
#[cfg(not(windows))]
{
path.join("sh").exists()
}
})
})
}
fn prepare_tokio_command( fn prepare_tokio_command(
command: &str, command: &str,
cwd: &std::path::Path, cwd: &std::path::Path,
@ -224,8 +247,16 @@ fn prepare_tokio_command(
return prepared; return prepared;
} }
let mut prepared = TokioCommand::new("sh"); let mut prepared = if cfg!(target_os = "windows") && !sh_exists() {
prepared.arg("-lc").arg(command).current_dir(cwd); let mut p = TokioCommand::new("cmd");
p.arg("/C").arg(command);
p
} else {
let mut p = TokioCommand::new("sh");
p.arg("-lc").arg(command);
p
};
prepared.current_dir(cwd);
if sandbox_status.filesystem_active { if sandbox_status.filesystem_active {
prepared.env("HOME", cwd.join(".sandbox-home")); prepared.env("HOME", cwd.join(".sandbox-home"));
prepared.env("TMPDIR", cwd.join(".sandbox-tmp")); prepared.env("TMPDIR", cwd.join(".sandbox-tmp"));

View File

@ -170,6 +170,13 @@ impl ConfigLoader {
let config_home = std::env::var_os("CLAUDE_CONFIG_HOME") let config_home = std::env::var_os("CLAUDE_CONFIG_HOME")
.map(PathBuf::from) .map(PathBuf::from)
.or_else(|| std::env::var_os("HOME").map(|home| PathBuf::from(home).join(".claude"))) .or_else(|| std::env::var_os("HOME").map(|home| PathBuf::from(home).join(".claude")))
.or_else(|| {
if cfg!(target_os = "windows") {
std::env::var_os("USERPROFILE").map(|home| PathBuf::from(home).join(".claude"))
} else {
None
}
})
.unwrap_or_else(|| PathBuf::from(".claude")); .unwrap_or_else(|| PathBuf::from(".claude"));
Self { cwd, config_home } Self { cwd, config_home }
} }

View File

@ -327,9 +327,15 @@ fn credentials_home_dir() -> io::Result<PathBuf> {
if let Some(path) = std::env::var_os("CLAUDE_CONFIG_HOME") { if let Some(path) = std::env::var_os("CLAUDE_CONFIG_HOME") {
return Ok(PathBuf::from(path)); return Ok(PathBuf::from(path));
} }
let home = std::env::var_os("HOME") if let Some(path) = std::env::var_os("HOME") {
.ok_or_else(|| io::Error::new(io::ErrorKind::NotFound, "HOME is not set"))?; return Ok(PathBuf::from(path).join(".claude"));
Ok(PathBuf::from(home).join(".claude")) }
if cfg!(target_os = "windows") {
if let Some(path) = std::env::var_os("USERPROFILE") {
return Ok(PathBuf::from(path).join(".claude"));
}
}
Err(io::Error::new(io::ErrorKind::NotFound, "HOME or USERPROFILE is not set"))
} }
fn read_credentials_root(path: &PathBuf) -> io::Result<Map<String, Value>> { fn read_credentials_root(path: &PathBuf) -> io::Result<Map<String, Value>> {

View File

@ -107,11 +107,23 @@ impl SandboxConfig {
#[must_use] #[must_use]
pub fn detect_container_environment() -> ContainerEnvironment { pub fn detect_container_environment() -> ContainerEnvironment {
let proc_1_cgroup = fs::read_to_string("/proc/1/cgroup").ok(); let proc_1_cgroup = if cfg!(target_os = "linux") {
fs::read_to_string("/proc/1/cgroup").ok()
} else {
None
};
detect_container_environment_from(SandboxDetectionInputs { detect_container_environment_from(SandboxDetectionInputs {
env_pairs: env::vars().collect(), env_pairs: env::vars().collect(),
dockerenv_exists: Path::new("/.dockerenv").exists(), dockerenv_exists: if cfg!(target_os = "linux") {
containerenv_exists: Path::new("/run/.containerenv").exists(), Path::new("/.dockerenv").exists()
} else {
false
},
containerenv_exists: if cfg!(target_os = "linux") {
Path::new("/run/.containerenv").exists()
} else {
false
},
proc_1_cgroup: proc_1_cgroup.as_deref(), proc_1_cgroup: proc_1_cgroup.as_deref(),
}) })
} }