关于编写Windows程序中启动兼容性问题

Posted halone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于编写Windows程序中启动兼容性问题相关的知识,希望对你有一定的参考价值。

之前用qt4编写Windows程序的时候遇到了一个软件在系统的兼容性问题:用户在win10系统下使用这个程序的时候,如果没有用低于win10版本的兼容模式运行的时候,存在运行某部分功能的时候无法使用的问题。

这个问题一开始困扰了我很久,那时我认为的解决方案有两种:

1.将软件从qt4迁移到qt5上

不过在对软件的大小是有限制的,之所以一开始用qt4写这个项目是因为qt4的模块相对于qt5来说小很多,因此这个方案被我否决了

2.程序自启动的时候将系统兼容性设置为win10以下的版本类型

 

在否决了第一个方案之后,只能采取第二种方案。

windows程序的兼容性是由注册表控制的,其位置Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers

以qt4中将程序设置为win7兼容模式为例子(需要重启才能生效,因为是程序启动后注册表信息才被修改的,读者可自行判断所处系统再进行相应的修改):

HKEY hKey;
    LPCTSTR strSubKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers";
    long lRet = ::RegOpenKeyEx( HKEY_CURRENT_USER, strSubKey, 0, KEY_WRITE, &hKey );
    if ( lRet == ERROR_SUCCESS )
    

        const size_t cSize = strlen(QCoreApplication::applicationFilePath().replace("/","\\").toStdString().c_str())+1;
        wchar_t* wc = new wchar_t[cSize];
        MultiByteToWideChar(CP_ACP, 0, QCoreApplication::applicationFilePath().replace("/","\\").toStdString().c_str(),
                            strlen(QCoreApplication::applicationFilePath().replace("/","\\").toStdString().c_str()) + 1, wc, sizeof(wchar_t)* cSize/ sizeof(wc[0]));

        //QCoreApplication::applicationFilePath().replace("/","\\").toLocal8Bit().data();
        lRet  = ::RegSetValueEx( hKey,wc, NULL, REG_SZ, (LPBYTE)(L"~ WIN7RTM"),18);  //WIN7RTM可以更换成你想要的兼容的类型
        RegCloseKey( hKey );
    

在对注册表信息修改之后,程序本身的兼容性问题并没有得到解决,还得进行重启后才生效,之后再加入重启程序的函数即可。

重启之前必须进行对是否已经在注册表中写入兼容信息进行判断,若已经兼容,那么注册表信息就不必再注册并且重启软件了。

值得注意的是,注册表是通过写入程序的相对位置来判断是否要用兼容性打开那个文件,因此,若程序之前已经兼容性运行过了,如果程序的位置再发生改变之后,再启动的话话并不会以兼容模式运行这个程序,此时又得在注册表中重新写入兼容性信息并且删除之前的兼容性信息后重启程序。

 

以上是关于关于编写Windows程序中启动兼容性问题的主要内容,如果未能解决你的问题,请参考以下文章

如何测量代码片段的调用次数和经过时间

30秒就能看懂的JavaScript 代码片段

关于片段生命周期

由于与64位的windows不兼容此程序或功能无法启动或运行

怎么用c++编写一个Windows服务程序来监控另一个程序,崩溃后重新启动。

关于Activity和Fragment生命周期的问题