Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 39fab2cb16 | |||
| e1333ccb78 | |||
| e3b36d958d |
232
docs/常见问题与解决方案.md
Normal file
232
docs/常见问题与解决方案.md
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
# 常见问题与解决方案
|
||||||
|
|
||||||
|
本文档记录远程音量控制项目在开发和部署过程中遇到的常见问题及解决方案,避免重复踩坑。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 问题清单
|
||||||
|
|
||||||
|
### 1. Windows 启动脚本无法运行(换行符问题)
|
||||||
|
|
||||||
|
**问题描述:**
|
||||||
|
在 Windows 上双击运行 `启动监控.bat` 时,脚本无法执行或报错。
|
||||||
|
|
||||||
|
**原因:**
|
||||||
|
Linux/Unix 使用 LF (`\n`) 换行符,Windows 使用 CRLF (`\r\n`) 换行符。Git 在 Linux 环境下编辑后保存的是 LF 格式。
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
```bash
|
||||||
|
# 转换换行符为 CRLF
|
||||||
|
cd scripts/
|
||||||
|
sed -i 's/$/\r/' 启动监控.bat
|
||||||
|
|
||||||
|
# 验证
|
||||||
|
file 启动监控.bat
|
||||||
|
# 输出应包含:with CRLF line terminators
|
||||||
|
```
|
||||||
|
|
||||||
|
**预防措施:**
|
||||||
|
- 在 `.gitattributes` 中配置:`*.bat text eol=crlf`
|
||||||
|
- 使用支持跨平台换行符的编辑器(VSCode、Notepad++)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Windows 启动脚本中文乱码(编码问题)
|
||||||
|
|
||||||
|
**问题描述:**
|
||||||
|
在中文 Windows 上运行 `启动监控.bat` 时,中文显示为乱码。
|
||||||
|
|
||||||
|
**原因:**
|
||||||
|
Windows CMD 默认使用 ANSI 编码(中文系统为 GBK),而脚本保存为 UTF-8 编码。
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
```bash
|
||||||
|
# 方法 1:使用 Python 转换编码
|
||||||
|
python3 -c "
|
||||||
|
with open('启动监控.bat', 'r', encoding='utf-8') as f:
|
||||||
|
text = f.read()
|
||||||
|
with open('启动监控.bat', 'wb') as f:
|
||||||
|
f.write(text.encode('gbk'))
|
||||||
|
"
|
||||||
|
|
||||||
|
# 方法 2:使用 iconv
|
||||||
|
iconv -f UTF-8 -t GBK 启动监控.bat > 启动监控.bat.tmp && mv 启动监控.bat.tmp 启动监控.bat
|
||||||
|
|
||||||
|
# 设置代码页为简体中文
|
||||||
|
# 在 bat 文件开头添加:chcp 936 >nul
|
||||||
|
```
|
||||||
|
|
||||||
|
**bat 文件头部配置:**
|
||||||
|
```batch
|
||||||
|
@echo off
|
||||||
|
chcp 936 >nul ← 简体中文代码页
|
||||||
|
title 远程连接音量自动调节器
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
**预防措施:**
|
||||||
|
- Windows bat 脚本使用 ANSI (GBK) 编码保存
|
||||||
|
- 在文档中明确标注编码要求
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. Python UnboundLocalError: cannot access local variable 'logger'
|
||||||
|
|
||||||
|
**问题描述:**
|
||||||
|
运行程序时报错:
|
||||||
|
```
|
||||||
|
UnboundLocalError: cannot access local variable 'logger' where it is not associated with a value
|
||||||
|
```
|
||||||
|
|
||||||
|
**原因:**
|
||||||
|
在 `main()` 函数内部使用 `logger = setup_logging()` 重新赋值,导致 `logger` 变成局部变量,后续使用时作用域冲突。
|
||||||
|
|
||||||
|
**错误代码示例:**
|
||||||
|
```python
|
||||||
|
logger = setup_logging() # 全局 logger
|
||||||
|
|
||||||
|
def main():
|
||||||
|
logger = setup_logging(config_path) # ❌ 这让 logger 变成局部变量
|
||||||
|
logger.info(...) # UnboundLocalError!
|
||||||
|
```
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
```python
|
||||||
|
logger = setup_logging() # 全局 logger
|
||||||
|
|
||||||
|
def _apply_log_config(config_path):
|
||||||
|
"""更新日志等级,不重新赋值 logger"""
|
||||||
|
...
|
||||||
|
logger.setLevel(log_level) # 直接修改全局 logger
|
||||||
|
|
||||||
|
def main():
|
||||||
|
_apply_log_config(config_path) # ✅ 不重新赋值
|
||||||
|
logger.info(...) # 正常工作
|
||||||
|
```
|
||||||
|
|
||||||
|
**预防措施:**
|
||||||
|
- 避免在函数内部重新赋值全局 logger 变量
|
||||||
|
- 使用 `logger.setLevel()` 修改日志等级,而不是重新创建 logger
|
||||||
|
- 如必须重新赋值,使用 `global logger` 声明
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4. 日志等级未按配置文件设置
|
||||||
|
|
||||||
|
**问题描述:**
|
||||||
|
配置文件中设置了 `level = DEBUG`,但日志仍然只显示 INFO 及以上级别。
|
||||||
|
|
||||||
|
**原因:**
|
||||||
|
程序启动时初始化了日志配置,但加载配置文件后没有应用配置文件中的日志等级。
|
||||||
|
|
||||||
|
**解决方案:**
|
||||||
|
```python
|
||||||
|
def setup_logging(config_path=None):
|
||||||
|
"""根据配置文件设置日志等级"""
|
||||||
|
log_level = logging.INFO # 默认等级
|
||||||
|
|
||||||
|
# 从配置文件读取日志等级
|
||||||
|
if config_path and Path(config_path).exists():
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_path, encoding='utf-8')
|
||||||
|
if 'logging' in config and 'level' in config['logging']:
|
||||||
|
level_str = config['logging']['level'].upper()
|
||||||
|
log_level = getattr(logging, level_str, logging.INFO)
|
||||||
|
|
||||||
|
logging.basicConfig(level=log_level, ...)
|
||||||
|
return logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def _apply_log_config(config_path):
|
||||||
|
"""应用配置文件中的日志等级"""
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_path, encoding='utf-8')
|
||||||
|
level_str = config['logging']['level'].upper()
|
||||||
|
logger.setLevel(getattr(logging, level_str, logging.INFO))
|
||||||
|
```
|
||||||
|
|
||||||
|
**配置文件示例:**
|
||||||
|
```ini
|
||||||
|
[logging]
|
||||||
|
level = INFO
|
||||||
|
log_file = remote_volume.log
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ 开发环境配置建议
|
||||||
|
|
||||||
|
### Git 配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 全局配置换行符(Windows 用户)
|
||||||
|
git config --global core.autocrlf true
|
||||||
|
|
||||||
|
# 全局配置换行符(Linux/Mac 用户)
|
||||||
|
git config --global core.autocrlf input
|
||||||
|
|
||||||
|
# 项目级配置(推荐)
|
||||||
|
# 在项目根目录创建 .gitattributes
|
||||||
|
echo "*.bat text eol=crlf" >> .gitattributes
|
||||||
|
echo "*.cmd text eol=crlf" >> .gitattributes
|
||||||
|
echo "*.ps1 text eol=lf" >> .gitattributes
|
||||||
|
echo "*.py text eol=lf" >> .gitattributes
|
||||||
|
```
|
||||||
|
|
||||||
|
### 编辑器配置
|
||||||
|
|
||||||
|
**VSCode 设置:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"files.eol": "\n",
|
||||||
|
"files.encoding": "utf8",
|
||||||
|
"[batch]": {
|
||||||
|
"files.encoding": "gbk",
|
||||||
|
"files.eol": "\r\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Notepad++ 设置:**
|
||||||
|
- 菜单 → 编码 → 选择 ANSI(针对 bat 文件)
|
||||||
|
- 菜单 → 编辑 → EOL 转换 → 转换为 Windows 格式(CRLF)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 版本修复记录
|
||||||
|
|
||||||
|
| 版本 | 修复内容 | 日期 |
|
||||||
|
|------|---------|------|
|
||||||
|
| v1.1.0 | 启动脚本添加窗口设置,移除依赖自动安装 | 2026-03-20 |
|
||||||
|
| v1.1.1 | 修复 logger 作用域 UnboundLocalError | 2026-03-20 |
|
||||||
|
| v1.1.2 | 修复 bat 文件中文乱码(UTF-8 → GBK) | 2026-03-20 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔍 排查步骤
|
||||||
|
|
||||||
|
遇到类似问题时的排查流程:
|
||||||
|
|
||||||
|
1. **检查文件编码**
|
||||||
|
```bash
|
||||||
|
file 文件名.bat
|
||||||
|
# 或
|
||||||
|
chardet 文件名.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **检查换行符**
|
||||||
|
```bash
|
||||||
|
file 文件名.bat
|
||||||
|
# 查看是否包含:with CRLF line terminators
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **检查 Python 作用域**
|
||||||
|
- 搜索函数内是否有 `logger =` 赋值
|
||||||
|
- 检查是否缺少 `global logger` 声明
|
||||||
|
|
||||||
|
4. **检查日志配置**
|
||||||
|
- 确认配置文件路径正确
|
||||||
|
- 确认 `[logging] level` 格式正确
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*最后更新:2026-03-20*
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
@echo off
|
@echo off
|
||||||
title 远程连接音量自动调节器 -By:LeeQwQ
|
title 远程连接音量自动调节器 -By:LeeQwQ
|
||||||
mode con cols=65 lines=18
|
mode con cols=65 lines=18
|
||||||
color 0B
|
color 0B
|
||||||
chcp 65001 >nul
|
chcp 936 >nul
|
||||||
cls
|
cls
|
||||||
echo ========================================
|
echo ========================================
|
||||||
echo 远程连接音量自动调节器
|
echo 远程连接音量自动调节器
|
||||||
echo Remote Volume Monitor
|
echo Remote Volume Monitor
|
||||||
echo ========================================
|
echo ========================================
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM 检查 Python
|
REM 检查 Python
|
||||||
python --version >nul 2>&1
|
python --version >nul 2>&1
|
||||||
if errorlevel 1 (
|
if errorlevel 1 (
|
||||||
echo [错误] 未找到 Python,请先安装 Python 3.8+
|
echo [错误] 未找到 Python,请先安装 Python 3.8+
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo [启动] 开始监控远程连接...
|
echo [启动] 开始监控远程连接...
|
||||||
echo [提示] 按 Ctrl+C 停止监控
|
echo [提示] 按 Ctrl+C 停止监控
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM 启动监控程序(从 scripts 目录调用 src 和 config)
|
REM 启动监控程序(从 scripts 目录调用 src 和 config)
|
||||||
python "%~dp0..\src\remote_volume_monitor.py" --config "%~dp0..\config\config.ini"
|
python "%~dp0..\src\remote_volume_monitor.py" --config "%~dp0..\config\config.ini"
|
||||||
|
|
||||||
pause
|
pause
|
||||||
|
|||||||
@@ -51,6 +51,22 @@ def setup_logging(config_path=None):
|
|||||||
)
|
)
|
||||||
return logging.getLogger(__name__)
|
return logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def _apply_log_config(config_path):
|
||||||
|
"""根据配置文件更新日志等级(不重新创建 logger)"""
|
||||||
|
if not Path(config_path).exists():
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(config_path, encoding='utf-8')
|
||||||
|
if 'logging' in config and 'level' in config['logging']:
|
||||||
|
level_str = config['logging']['level'].upper()
|
||||||
|
log_level = getattr(logging, level_str, logging.INFO)
|
||||||
|
logger.setLevel(log_level)
|
||||||
|
logger.info(f"📝 日志等级:{level_str}")
|
||||||
|
except Exception as e:
|
||||||
|
pass # 读取失败保持当前等级
|
||||||
|
|
||||||
logger = setup_logging()
|
logger = setup_logging()
|
||||||
|
|
||||||
|
|
||||||
@@ -561,16 +577,16 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
config.read(config_path, encoding='utf-8')
|
config.read(config_path, encoding='utf-8')
|
||||||
logger.info(f"✓ 已加载:{config_path}")
|
logger.info(f"✓ 已加载:{config_path}")
|
||||||
# 重新初始化日志(使用配置文件中的日志等级)
|
# 重新配置日志等级(使用配置文件中的日志等级)
|
||||||
logger = setup_logging(str(config_path))
|
_apply_log_config(str(config_path))
|
||||||
else:
|
else:
|
||||||
default_config = Path(__file__).parent.parent / 'config' / 'config.ini'
|
default_config = Path(__file__).parent.parent / 'config' / 'config.ini'
|
||||||
if default_config.exists():
|
if default_config.exists():
|
||||||
config.read(default_config, encoding='utf-8')
|
config.read(default_config, encoding='utf-8')
|
||||||
logger.info(f"✓ 已加载默认:{default_config}")
|
logger.info(f"✓ 已加载默认:{default_config}")
|
||||||
config_path = str(default_config)
|
config_path = str(default_config)
|
||||||
# 重新初始化日志(使用配置文件中的日志等级)
|
# 重新配置日志等级(使用配置文件中的日志等级)
|
||||||
logger = setup_logging(config_path)
|
_apply_log_config(config_path)
|
||||||
else:
|
else:
|
||||||
config['volume'] = {'remote_volume': str(args.volume)}
|
config['volume'] = {'remote_volume': str(args.volume)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user