开发原因:每次设置都需要点来点去的,而且网站共享软件不支持http需要改注册表,设置也比较麻烦,主要为了方便小白,所以就开发这款工具直接一步到位的工具。
软件界面:
功能说明:
1.0
检查管理员权限,强行要求必须管理员运行获取系统版本信息增加HTTP WebDAV支持选项勾选自动改注册表并重启WebClient服务,添加对大文件支持增加挂载失败的常见错误提示。增加自定义信息挂载功能。
1.5
取消HTTP WebDAV支持选项勾选自动内部处理。添加了配置文件自动保存下次直接读取添加了批量添加功能
需要其他功能的请留言。
源码:
[Python] - import os
- import sys
- import ctypes
- import platform
- import subprocess
- import tkinter as tk
- from tkinter import messagebox, ttk
- import winreg
- import json
- from urllib.parse import urlparse
- def is_admin():
- """检查是否以管理员权限运行"""
- try:
- return ctypes.windll.shell32.IsUserAnAdmin()
- except:
- return False
- def require_admin():
- """如果未以管理员运行,则重新启动"""
- if not is_admin():
- ctypes.windll.shell32.ShellExecuteW(
- None, "runas", sys.executable, " ".join(sys.argv), None, 1)
- sys.exit()
- def get_windows_version():
- """获取Windows系统版本信息"""
- return platform.platform()
- def enable_http_webdav():
- """启用HTTP WebDAV支持"""
- try:
- # 修改注册表以允许基本身份验证
- subprocess.run([
- 'reg', 'add',
- 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\WebClient\\Parameters',
- '/v', 'BasicAuthLevel', '/t', 'REG_DWORD', '/d', '2', '/f'
- ], check=True)
- # 设置更大的文件大小限制(解决大文件问题)
- subprocess.run([
- 'reg', 'add',
- 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\WebClient\\Parameters',
- '/v', 'FileSizeLimitInBytes', '/t', 'REG_DWORD', '/d', '0xFFFFFFFF', '/f'
- ], check=True)
- # 重启WebClient服务
- subprocess.run(['net', 'stop', 'webclient'], check=True)
- subprocess.run(['net', 'start', 'webclient'], check=True)
- return True, "HTTP WebDAV支持已启用"
- except subprocess.CalledProcessError as e:
- return False, f"启用HTTP WebDAV失败: {e}"
- except Exception as e:
- return False, f"未知错误: {str(e)}"
- def check_webclient_service():
- """检查WebClient服务状态"""
- try:
- result = subprocess.run(
- ['sc', 'query', 'webclient'],
- capture_output=True,
- text=True
- )
- return "RUNNING" in result.stdout
- except Exception as e:
- return False
- def url_to_unc(server):
- """将WebDAV URL转换为UNC路径"""
- parsed = urlparse(server)
- scheme = parsed.scheme.lower()
- host = parsed.hostname
- port = parsed.port
- path = parsed.path.lstrip('/')
- if scheme == 'http':
- ssl = ''
- default_port = 80
- elif scheme == 'https':
- ssl = '@SSL'
- default_port = 443
- else:
- raise ValueError("仅支持HTTP或HTTPS协议")
- if port and port != default_port:
- unc_host = f"{host}@{port}"
- else:
- unc_host = host
- unc = f"\\\\{unc_host}{ssl}\\DavWWWRoot\\{path}"
- return unc
- def set_drive_label(drive_letter, nickname):
- """设置驱动器标签(支持中文)"""
- try:
- # 使用 label 命令设置驱动器名称
- subprocess.run(['label', f'{drive_letter}:', nickname], check=True, shell=True)
- return True, "驱动器标签设置成功"
- except subprocess.CalledProcessError as e:
- return False, f"设置驱动器标签失败: {e}"
- except Exception as e:
- return False, f"设置驱动器标签失败: {str(e)}"
- def mount_webdav(server, drive_letter, username=None, password=None, nickname=None):
- """挂载WebDAV到本地驱动器并设置昵称"""
- try:
- unc = url_to_unc(server)
- # 先尝试取消可能存在的旧映射
- subprocess.run(['net', 'use', f'{drive_letter}:', '/delete', '/y'],
- stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
- # 构造net use命令
- cmd = ['net', 'use', f'{drive_letter}:', unc, '/persistent:yes']
- if username:
- cmd.extend(['/user:' + username])
- if password:
- cmd.append(password)
- # 执行挂载命令
- result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
- if result.returncode == 0:
- # 设置驱动器标签
- if nickname:
- success, message = set_drive_label(drive_letter, nickname)
- if not success:
- return True, f"挂载成功,但{message}"
- return True, "挂载成功"
- else:
- error_msg = result.stderr or "未知错误"
- # 常见错误代码处理
- if "67" in error_msg:
- return False, "错误67: 找不到网络名。请检查:\n1. WebDAV服务器地址是否正确\n2. 服务器是否运行\n3. 防火墙是否阻止连接"
- elif "1219" in error_msg:
- return False, "错误1219: 已有其他用户使用相同凭证连接。请先断开所有连接或重启电脑。"
- elif "1326" in error_msg:
- return False, "错误1326: 用户名或密码错误。"
- else:
- return False, error_msg
- except subprocess.TimeoutExpired:
- return False, "连接超时,请检查网络连接"
- except ValueError as ve:
- return False, str(ve)
- except Exception as e:
- return False, str(e)
- class WebDAVMounterApp:
- def __init__(self, root):
- self.root = root
- self.root.title("WebDAV 挂载工具 by吾爱破解")
- self.root.geometry("500x650")
- # 系统信息
- self.windows_version = get_windows_version()
- # 配置列表
- self.configs = []
- self.load_configs()
- # 创建UI
- self.create_ui()
- # 强制启用HTTP WebDAV支持
- self.check_webdav_support()
- def load_configs(self):
- """加载配置文件"""
- config_file = 'config.json'
- try:
- with open(config_file, 'r', encoding='utf-8') as f:
- self.configs = json.load(f)
- except FileNotFoundError:
- with open(config_file, 'w', encoding='utf-8') as f:
- json.dump([], f)
- except json.JSONDecodeError:
- self.configs = []
- def save_configs(self):
- """保存配置到文件"""
- config_file = 'config.json'
- with open(config_file, 'w', encoding='utf-8') as f:
- json.dump(self.configs, f, indent=4, ensure_ascii=False)
- def create_ui(self):
- """创建用户界面"""
- # 系统信息标签
- ttk.Label(self.root, text=f"系统版本: {self.windows_version}").pack(pady=5)
- # 分隔线
- ttk.Separator(self.root, orient='horizontal').pack(fill='x', pady=10)
- # 单挂载部分
- single_frame = ttk.LabelFrame(self.root, text="单个挂载", padding=(10, 5))
- single_frame.pack(pady=10, fill='x')
- ttk.Label(single_frame, text="WebDAV服务器地址 (例如: http://server.com/path):").pack()
- self.server_entry = ttk.Entry(single_frame, width=50)
- self.server_entry.pack()
- self.server_entry.insert(0, "http://example.com/webdav")
- ttk.Label(single_frame, text="本地驱动器盘符 (例如: Z):").pack()
- self.drive_entry = ttk.Entry(single_frame, width=5)
- self.drive_entry.pack()
- self.drive_entry.insert(0, "U")
- ttk.Label(single_frame, text="驱动器昵称 (支持中文,可选):").pack()
- self.nickname_entry = ttk.Entry(single_frame, width=20)
- self.nickname_entry.pack()
- ttk.Label(single_frame, text="用户名 (可选):").pack()
- self.user_entry = ttk.Entry(single_frame, width=20)
- self.user_entry.pack()
- ttk.Label(single_frame, text="密码 (可选):").pack()
- self.pass_entry = ttk.Entry(single_frame, width=20, show="*")
- self.pass_entry.pack()
- # 保存配置按钮
- ttk.Button(single_frame, text="保存配置", command=self.save_config).pack(pady=5)
- self.mount_btn = ttk.Button(
- single_frame,
- text="挂载 WebDAV",
- command=self.on_mount
- )
- self.mount_btn.pack(pady=10)
- # 批量挂载部分
- batch_frame = ttk.LabelFrame(self.root, text="批量挂载 (从config.json加载)", padding=(10, 5))
- batch_frame.pack(pady=10, fill='both', expand=True)
- columns = ("nickname", "server", "drive", "user")
- self.config_tree = ttk.Treeview(batch_frame, columns=columns, show="headings")
- self.config_tree.heading("nickname", text="昵称")
- self.config_tree.heading("server", text="服务器地址")
- self.config_tree.heading("drive", text="盘符")
- self.config_tree.heading("user", text="用户名")
- self.config_tree.pack(fill='both', expand=True)
- # 填充配置
- for config in self.configs:
- self.config_tree.insert("", tk.END, values=(
- config.get("nickname", ""),
- config.get("server", ""),
- config.get("drive", ""),
- config.get("user", "")
- ))
- self.batch_btn = ttk.Button(
- batch_frame,
- text="批量挂载",
- command=self.batch_mount
- )
- self.batch_btn.pack(pady=10)
- # 日志区域
- ttk.Label(self.root, text="日志:").pack()
- self.log_text = tk.Text(self.root, height=10, width=60)
- self.log_text.pack(pady=5)
- # 状态标签
- self.status_label = ttk.Label(
- self.root,
- text="准备就绪",
- foreground="blue",
- wraplength=400
- )
- self.status_label.pack()
- # 自动加载第一个配置
- if self.configs:
- first_config = self.configs[0]
- self.server_entry.delete(0, tk.END)
- self.server_entry.insert(0, first_config.get("server", ""))
- self.drive_entry.delete(0, tk.END)
- self.drive_entry.insert(0, first_config.get("drive", ""))
- self.nickname_entry.delete(0, tk.END)
- self.nickname_entry.insert(0, first_config.get("nickname", ""))
- self.user_entry.delete(0, tk.END)
- self.user_entry.insert(0, first_config.get("user", ""))
- self.pass_entry.delete(0, tk.END)
- self.pass_entry.insert(0, first_config.get("pass", ""))
- def save_config(self):
- """保存当前输入的配置到config.json"""
- server = self.server_entry.get().strip()
- drive = self.drive_entry.get().strip().upper()
- nickname = self.nickname_entry.get().strip() or ""
- username = self.user_entry.get().strip() or ""
- password = self.pass_entry.get().strip() or ""
- if not server or not drive:
- messagebox.showerror("错误", "请输入服务器地址和驱动器盘符")
- return
- if len(drive) != 1 or not drive.isalpha():
- messagebox.showerror("错误", "驱动器盘符必须是单个字母 (A-Z)")
- return
- # 检查是否已存在相同配置
- for config in self.configs:
- if config.get("server") == server and config.get("drive") == drive:
- messagebox.showinfo("信息", "此配置已存在")
- return
- # 添加新配置
- new_config = {
- "server": server,
- "drive": drive,
- "nickname": nickname,
- "user": username,
- "pass": password
- }
- self.configs.append(new_config)
- self.save_configs()
- # 更新Treeview
- self.config_tree.insert("", tk.END, values=(nickname, server, drive, username))
- self.log_text.insert(tk.END, f"配置已保存: {nickname or server} 到 {drive}:\n")
- messagebox.showinfo("成功", "配置已保存到config.json")
- def check_webdav_support(self):
- """强制启用HTTP WebDAV支持"""
- self.status_label.config(
- text="正在启用WebClient服务...",
- foreground="orange"
- )
- self.root.update()
- success, message = enable_http_webdav()
- if success:
- self.status_label.config(
- text=message,
- foreground="green"
- )
- self.log_text.insert(tk.END, message + "\n")
- else:
- self.status_label.config(
- text=message,
- foreground="red"
- )
- self.log_text.insert(tk.END, message + "\n")
- messagebox.showerror("错误", message)
- def on_mount(self):
- """单个挂载按钮点击事件"""
- server = self.server_entry.get().strip()
- drive = self.drive_entry.get().strip().upper()
- nickname = self.nickname_entry.get().strip() or None
- username = self.user_entry.get().strip() or None
- password = self.pass_entry.get().strip() or None
- if not server or not drive:
- messagebox.showerror("错误", "请输入服务器地址和驱动器盘符")
- return
- if len(drive) != 1 or not drive.isalpha():
- messagebox.showerror("错误", "驱动器盘符必须是单个字母 (A-Z)")
- return
- self.status_label.config(text="正在尝试挂载...", foreground="blue")
- self.mount_btn.config(state='disabled')
- self.root.update()
- success, message = mount_webdav(server, drive, username, password, nickname)
- if success:
- self.status_label.config(text="挂载成功", foreground="green")
- messagebox.showinfo("成功", f"WebDAV已成功挂载到 {drive}: ({nickname or '无昵称'})")
- self.log_text.insert(tk.END, f"单个挂载成功: {nickname or server} 到 {drive}:\n")
- else:
- self.status_label.config(text=f"挂载失败: {message}", foreground="red")
- messagebox.showerror("错误", f"挂载失败:\n{message}")
- self.log_text.insert(tk.END, f"单个挂载失败: {nickname or server} - {message}\n")
- self.mount_btn.config(state='normal')
- def batch_mount(self):
- """批量挂载"""
- if not self.configs:
- messagebox.showinfo("信息", "没有配置可挂载。请编辑config.json或保存新配置。")
- return
- self.status_label.config(text="正在批量挂载...", foreground="blue")
- self.batch_btn.config(state='disabled')
- self.root.update()
- for config in self.configs:
- server = config.get("server")
- drive = config.get("drive", "").upper()
- nickname = config.get("nickname") or None
- username = config.get("user") or None
- password = config.get("pass") or None
- if not server or not drive:
- self.log_text.insert(tk.END, f"配置无效 (缺少server或drive): {config}\n")
- continue
- if len(drive) != 1 or not drive.isalpha():
- self.log_text.insert(tk.END, f"无效盘符 {drive} for {nickname or server}\n")
- continue
- success, message = mount_webdav(server, drive, username, password, nickname)
- if success:
- self.log_text.insert(tk.END, f"挂载成功: {nickname or server} 到 {drive}:\n")
- else:
- self.log_text.insert(tk.END, f"挂载失败: {nickname or server} - {message}\n")
- self.status_label.config(text="批量挂载完成", foreground="green")
- self.batch_btn.config(state='normal')
- if __name__ == "__main__":
- # 强制要求管理员权限
- require_admin()
- # 创建GUI
- root = tk.Tk()
- app = WebDAVMounterApp(root)
- # 设置窗口图标 (可选)
- try:
- root.iconbitmap(default='webdav.ico')
- except:
- pass
- root.mainloop()
复制代码
1.0下载地址: 打包exe文件
链接:https://pan.baidu.com/s/1yzZhgX0iLigZiCdmy1Cc3A?pwd=52pj 提取码:52pj
1.5下载地址: 打包exe文件
链接: https://pan.baidu.com/s/1CDDIQyJRmQ58TAW6UKaHQA?pwd=52pj 提取码:52pj
|