关于编写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 );
    }

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

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

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

原文地址:https://www.cnblogs.com/halone/p/10957867.html

时间: 2024-11-03 21:25:18

关于编写Windows程序中启动兼容性问题的相关文章

同一台Windows机器中启动多个Memcached服务

同一台Windows机器中启动多个Memcached服务 这就需要在一台机器上启动多个Memcached服务了. 假设Memcached在如下目录:C:\memcached\memcached.exe 在CMD中执行如下命令即可再安装一个Memcached服务(记得换个端口号啊!): sc create "Memcached Server1" start= auto binPath= "F:\memcached\memcached.exe -d runservice -m 3

[C#]在程序中启动另外一个程序

C#实现在程序中启动另外一个程序 ProcessStartInfo info = new ProcessStartInfo();    info.FileName = "notepad++.exe";//要启动的程序外部名称   info.Arguments = "1009.txt";//设置外部程序的启动参数    info.WorkingDirectory = @"D:\Users\Desktop";    Process pro;//申明一

WPF 程序中启动和关闭外部.exe程序

当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; u

Android 在一个程序中启动另一个程序

Android 开发有时需要在一个应用中启动另一个应用,比如Launcher加载所有的已安装的程序的列表,当点击图标时可以启动另一个应用. 一般我们知道了另一个应用的包名和MainActivity的名字之后便可以直接通过如下代码来启动: Intent intent = new Intent(Intent.ACTION_MAIN); intent.add

在Windows程序中启用console输出-2016.01.04

在某些时候,我们可能需要在Win32窗口应用程序中打开控制台窗口,打印一些消息,或者作为当前程序的另外一个人机交互界面,或者为了帮助调试程序.为了达到这种效果,需要了解函数AllocConsole和C-Runtime的freopen函数.AllocConsole函数会为当前的窗口程序申请一个Console窗口,下面MSDN对AllocConsole的介绍: The AllocConsole function allocates a new console for the calling proc

Android - 在一个应用程序中启动另外一个已经安装的应用程序或系统程序(前提是要知道该应用程序的主activity和包名)

//组件名称,第一个参数是应用程序的包名,后一个是这个应用程序的主Activity ComponentName com = new ComponentName("com.antroid.Test", "com.antroid.Test.TestActivity"); Intent  intent = new Intent(); //设置部件 intent.setComponent(com); startActivity(intent); 我们也可以使用下面的代码启动

windows程序中拷贝文件的选择

最近需要在Windows下拷贝大量小文件(数量在十万级别以上).写了些拷贝文件的小程序,竟然发现不同的选择,拷贝的速度有天壤之别! 现有这样的测试数据:1500+小文件,总大小10M左右.现用不同方法进行拷贝.: 方案1:调用SHFileOperation [cpp] view plain copy BOOL CUtility::CopyFolder(LPCTSTR lpszFromPath,LPCTSTR lpszToPath) { size_t nLengthFrm = _tcslen(lp

实体类在Windows程序中的高级应用--------------------》》心境是一种境界。

一.事务 我们在大家学到这,或多或少对事务都有一些理解了.今天的我也对事务有了更深一层的理解对我来说,我想与大家一起分享一下. 解析: 1.ADO.NET提供了事务处理功能 2.C#中开启事务 3.在咱们的SQL后台就不用开启事务了 4.eg.我要在FrmSW的窗体上添加年级,我们首先在数据库中在年级表中对其GradeName设置唯一约束,如果GradeName重复则事务会将其回滚,如GradeName不重复就会输出. string str = "data source=.;initial ca

Windows程序中加载并使用动态链接库

1 GetProcAddress() 1.1函数原型 GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址. 函数原型: FARPROC GetProcAddress( HMODULE hModule, // DLL模块句柄 LPCSTR lpProcName // 函数名 ); hModule [in] 包含此函数的DLL模块的句柄.LoadLibrary. AfxLoadLibrary  或者GetModuleHandle函数可以返回此句柄. lpProcName