新增AGC首页自定义工作目录
新增用户目录创建命令与首页接线 保持普通用户权限并避免ACL和UAC耦合 补充里程碑与实施计划
This commit is contained in:
@@ -811,6 +811,41 @@ pub(crate) async fn pick_local_project_directory(
|
||||
Ok(Some(path.to_string_lossy().into_owned()))
|
||||
}
|
||||
|
||||
/// Create a user-requested child directory using the current user's normal
|
||||
/// filesystem rights. This deliberately does not inspect or rewrite ACLs and
|
||||
/// never attempts elevation.
|
||||
#[tauri::command]
|
||||
pub(crate) fn create_local_project_directory(
|
||||
parent_path: String,
|
||||
directory_name: String,
|
||||
) -> Result<String, String> {
|
||||
let parent = Path::new(parent_path.trim());
|
||||
if parent.as_os_str().is_empty() || !parent.is_absolute() {
|
||||
return Err("父目录必须是绝对路径".to_string());
|
||||
}
|
||||
if project_path_has_control_chars(parent) {
|
||||
return Err("父目录不能包含控制字符".to_string());
|
||||
}
|
||||
if !parent.is_dir() {
|
||||
return Err("父目录不存在或不是文件夹".to_string());
|
||||
}
|
||||
let name = directory_name.trim();
|
||||
if name.is_empty() || name == "." || name == ".." || name.chars().any(|c| c == '/' || c == '\\')
|
||||
{
|
||||
return Err("目录名称无效".to_string());
|
||||
}
|
||||
if name.chars().any(|c| c.is_control()) {
|
||||
return Err("目录名称不能包含控制字符".to_string());
|
||||
}
|
||||
let target = parent.join(name);
|
||||
fs::create_dir(&target).map_err(|error| match error.kind() {
|
||||
std::io::ErrorKind::AlreadyExists => "目录已存在".to_string(),
|
||||
std::io::ErrorKind::PermissionDenied => "没有权限在此位置创建目录".to_string(),
|
||||
_ => format!("创建目录失败:{error}"),
|
||||
})?;
|
||||
Ok(target.to_string_lossy().into_owned())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn pick_local_file(app: tauri::AppHandle) -> Result<Option<String>, String> {
|
||||
let (sender, receiver) = tokio::sync::oneshot::channel();
|
||||
|
||||
@@ -2636,6 +2636,7 @@ fn main() {
|
||||
is_local_project_directory_non_empty,
|
||||
inspect_local_project_directory,
|
||||
pick_local_project_directory,
|
||||
create_local_project_directory,
|
||||
rename_local_game_project,
|
||||
suggest_automatic_project_name,
|
||||
polish_local_project_prompt,
|
||||
|
||||
@@ -895,14 +895,26 @@ export function useHomeProjectCreation({
|
||||
setProjectAction('creating');
|
||||
setStatus('正在选择新项目文件夹');
|
||||
try {
|
||||
const selectedPath = await invoke<string | null>(
|
||||
const parentPath = await invoke<string | null>(
|
||||
'pick_local_project_directory',
|
||||
projectPath.trim() ? { initialPath: projectPath.trim() } : undefined,
|
||||
);
|
||||
if (!selectedPath) {
|
||||
if (!parentPath) {
|
||||
setStatus('已取消');
|
||||
return;
|
||||
}
|
||||
const directoryName = window.prompt('请输入新目录名称');
|
||||
if (!directoryName?.trim()) {
|
||||
setStatus('已取消');
|
||||
return;
|
||||
}
|
||||
const selectedPath = await invoke<string>(
|
||||
'create_local_project_directory',
|
||||
{
|
||||
parentPath,
|
||||
directoryName: directoryName.trim(),
|
||||
},
|
||||
);
|
||||
setProjectPath(selectedPath);
|
||||
projectActionRef.current = null;
|
||||
setProjectAction(null);
|
||||
|
||||
Reference in New Issue
Block a user