我的程序报这个问题跟操作系统版本(是win7还是win10)无关,跟源字符集或可执行字符集的编码无关,是因为路径有错误导致的。记录一下排查过程,方便他人解决这个问题。
昨天运行项目代码,发现在界面上双击打开文件失效,这部分代码就用了QDesktopServices::openUrl(文件路径)来打开文件,看控制台输出:ShellExecute 'file:///D:/xxx/xxx/???.txt' failed (error 2),
刚开始觉得出现了乱码,是不是跟字符集有关,qDebug()输出一下路径,正常显示没有乱码,但ShellExecute这部分信息的中文乱码。
网上找解决办法,复现了跟这篇博文一样的结果:QDesktopServices简单使用,第1节的第(6)路径中出现中文报错,加上如下代码:
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF_8"));
结果如下:
其实这可以说明跟字符集的编码无关了。
于是又去了解ShellExecute,这是系统动态库Shell32.dll里的一个函数,想到昨天由于电脑卡死,把win7换成了win10操作系统, 于是猜测是不是win10的Shell32.dll跟win7的不同,网上没有查到不一样,但找到了Qt在Win10下调用系统的软键盘这篇博文,感觉真的跟操作系统版本有关。仿照,
ShellExecute(nullptr, L"open", (LPCWSTR)csProcess.utf16(), (LPCWSTR)params.utf16(), nullptr, SW_SHOWNORMAL);
想着把路径改成由QString类型改成LPCWSTR类型(头文件在windows.h,LPCWSTR和QString可以相互转换,使用(LPCWSTR)str.toStdWString().c_str()和QString::fromStrWString(lpcwstr)即可相互转换),但是参数不匹配。
于是想查看QDesktopServices和ShellExecute的关系,去看源码,QDesktopServices::openUrl()的实现涉及:QPlatformServices类,但这个类的源码没给出来,去官网也查不到(说好的开源呢!!!),于是放弃了。
尝试了这篇:Qt QDesktopServices打开中文路径里的所有方法,
(1) QString str(QStringLiteral("D:/新建文件夹"));
(2)在头文件里添加了如下: #ifdef Q_CC_MSVC #pragma execution_character_set("utf-8") #endif
(3)把路径里的反斜杠进行替换replace(":/",":\\")
(4)(QDir::toNativeSeparators(filePath)
(5)QDesktopServices::openUrl(QUrl(str, QUrl::TolerantMode));
均无效,想放弃了。
第二天想再尝试一下,于是复制了正确路径,然后再试,文件成功被打开,真实项目中所打开文件的路径很复杂,仔细对比区别,发现这个路径修改了,但没更新这个文件的路径(这是代码里的bug),于是打不开,原来只要路径正确就能打开!!!
最后讲一个判断文件路径是否指向文件的方法,将路径复制到电脑文件管理器的地址栏(在搜索栏旁边),如下图所示:
如果文件地址正确指向文件,回车一下就能打开文件,否则就不能打开文件。
参考文献:
QDesktopServices简单使用_kaixin_learn_qt_ing的博客-CSDN博客