欢迎各位兄弟 发布技术文章
这里的技术是共享的
以前上小祥的代码 ,,,win10 系统编码 使用 cp936 ,,,所以代码运行正常,,,win11 使用 utf-8,代码运行不正常
win10 系统编码 使用 cp936 ,,win11 使用 utf-8 ,,,如何写出兼容性的代码
在 Windows 系统中,不同版本可能使用不同的编码(如 Win10 常用 cp936,而 Win11 开始支持 utf-8),可以通过 尝试多种编码 或 动态检测系统编码 来实现兼容性。以下是几种解决方案:
使用 try-except 依次尝试 utf-8、cp936 甚至 gbk 等常见编码:
pythonimport subprocess def get_netsh_output(): cmd = ["netsh", "advfirewall", "show", "allprofiles", "state"] # 尝试 utf-8,fallback 到 cp936/gbk(Windows 10/11) for encoding in ["utf-8", "cp936", "gbk"]: try: result = subprocess.run( cmd, capture_output=True, text=True, encoding=encoding ) output = result.stdout.strip() if output: # 检查是否获取有效输出 return output except UnicodeDecodeError: continue # 继续尝试下一种编码 # 如果所有编码都失败,返回 raw bytes 并进行手动解码 result = subprocess.run(cmd, capture_output=True) return result.stdout.decode("utf-8", errors="replace") # 尽可能恢复 print("--- netsh output ---") print(get_netsh_output()) print("--------------------")
使用 locale 模块检测当前系统的默认编码:
pythonimport subprocess import locale # 获取系统默认编码(cp936 在中文 Windows 10 上,utf-8 在 Windows 11) system_encoding = locale.getpreferredencoding() result = subprocess.run( ["netsh", "advfirewall", "show", "allprofiles", "state"], capture_output=True, text=True, encoding=system_encoding # 使用系统编码 ) print("--- netsh output ---") print(result.stdout.strip()) print("--------------------")
注意:
locale.getpreferredencoding()可能返回cp936(中文 Win10)或utf-8(Win11),但也可能不完全准确。
universal_newlines=True (Python 3.7+)让 Python 自动处理编码(较宽松):
pythonresult = subprocess.run( ["netsh", "advfirewall", "show", "allprofiles", "state"], capture_output=True, universal_newlines=True # 无需指定 encoding,Python 会尽量解码 ) print("--- netsh output ---") print(result.stdout.strip()) print("--------------------")
适用场景:
universal_newlines=True会尝试用系统编码解码,但可能仍然遇到乱码。
| 方案 | 适用场景 | 优缺点 |
|---|---|---|
| 方法 1(尝试多种编码) | 兼容 Win10/Win11(不确定编码时) | ✅ 健壮性好 / ❌ 略微冗余 |
| 方法 2(动态检测系统编码) | 适用于大多数情况 | ✅ 符合系统实际编码 / ❌ 某些环境可能不准确 |
方法 3(universal_newlines=True) | 适用于简单情况 | ✅ 自动处理 / ❌ 若乱码仍需手动干预 |
推荐顺序:方法 1 > 方法 2 > 方法 3