WebDAV 挂载工具1.0
开发原因:每次设置都需要点来点去的,而且网站共享软件不支持http需要改注册表,设置也比较麻烦,主要为了方便小白,所以就开发这款工具直接一步到位的工具。
软件界面:
功能说明:
1.0
检查管理员权限,强行要求必须管理员运行获取系统版本信息增加HTTP WebDAV支持选项勾选自动改注册表并重启WebClient服务,添加对大文件支持增加挂载失败的常见错误提示。增加自定义信息挂载功能。
1.5
取消HTTP WebDAV支持选项勾选自动内部处理。添加了配置文件自动保存下次直接读取添加了批量添加功能
需要其他功能的请留言。
源码:
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
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
试了一下,不支持停用,退出后,不能保存配置,下将打开要重新设置。而且挂载只能以网域映射方式挂载,不能以本地硬盘方式挂载。 最好能默认强制 http 勾选,另外,默认打开是账号密码登录框,设置框可以弄个按钮进去配置添加信息。 终于碰上这样的软件了。好用! 感谢分享,在用RaiDrive,可以挂载NAS,不知道这个能不能支持 电脑上好像用的smb现在 感谢分享,不错的软件 很不错,Nice 很不多。谢谢分享了。整好需要呢。 感谢分享,先收藏备用!
页:
[1]
2