泰州做网站公司,wordpress tooltipster,软件定制开发招标,彩票网站建设方案因为小项目需要创建windows服务#xff0c;安装微软官方示例一切都挺顺利#xff0c;代码运行后发现配置的信息在系统里显示乱码。打开注册表发现的确是乱码。这就排除软件读取得问题#xff0c;而是调用ChangeServiceConfig系统函数写入时就发生了乱码。让我在网上查找了一… 因为小项目需要创建windows服务安装微软官方示例一切都挺顺利代码运行后发现配置的信息在系统里显示乱码。打开注册表发现的确是乱码。这就排除软件读取得问题而是调用ChangeServiceConfig系统函数写入时就发生了乱码。让我在网上查找了一下午都没有结果。主要是我是按照官方的示例创建的呀既然是官方示例出现bug的可能就极小。没法静下心来看官方文档吧。功夫不负有心人终于让我发现了问题。记录一下错误过程 出现问题的地方是windows的很多函数都会用宏预先处理调用函数。因为历史的原因很多函数都会有不同的变种以自动适配函数和数据类型。比如ChangeServiceConfig2A 和 ChangeServiceConfig2W 这两个函数其功能是一样的。主要是数据类型发生了改变。SERVICE_DESCRIPTIONA,SERVICE_DESCRIPTIONW这两中数据类型服务于上面两种不同的函数。 当我们调用ChangeServiceConfig2时编译器会根据开发环境自动识别选用ChangeServiceConfig2A 或 ChangeServiceConfig2W。我出现问题的地方就是编译器竟然给我混用了ChangeServiceConfig2A 函数这个函数是为了兼容以前的老系统版本的所使用的数据类型是LPSTR。我的开发环境是win11使用的是LPWSTR数据类型。所以系统显示的配置信息是乱码。
一、 我的开发环境是windows11 QT。这是我的开发环境。 二、我按官方示例创建了服务包括创建、卸载、停止、更新服务配置信息等等。在更新服务配置信息部分出现了写入乱码的问题下面源码是修正过运行正确的
//添加修改服务描述信息
BOOL NpfConfig::SelfChangeServiceConfig(QString m_lpszDriverName, QString m_description)
{SC_HANDLE schManager;SC_HANDLE schService;SERVICE_DESCRIPTIONW lpInfo; LPCWSTR lpszDriverName;LPWSTR description;std::wstring wLpszDriverName m_lpszDriverName.toStdWString();lpszDriverName wLpszDriverName.c_str();std::wstring wDescription m_description.toStdWString();description wDescription.data();lpInfo.lpDescription description;qDebug()lpInfo.lpDescription;schManager OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (NULL schManager){return FALSE;}schService OpenService(schManager, lpszDriverName, SERVICE_ALL_ACCESS);if (NULL schService){CloseServiceHandle(schManager);return FALSE;}if (!ChangeServiceConfig2W(schService,SERVICE_CONFIG_DESCRIPTION,lpInfo)){qDebug()修改服务描述信息错误GetLastError();return false;}else{qDebug()修改服务描述信息成功;}CloseServiceHandle(schService);CloseServiceHandle(schManager);return true;}
三、这是读取服务配置信息的函数。修正过可以正常运行的。需要说明的是上面的代码和下面的代码所用到的数据类型必须一致。我所出现的问题就是相信了编译器给我预处理的选择。最后我手动指定所用函数而不是让编译器推荐的宏通用函数。
//查询服务描述项
BOOL NpfConfig::DoQueryDescription(QString m_serviceName)
{DWORD dwBytesNeeded, cbBufSize0, dwError;LPSERVICE_DESCRIPTIONW lpsd;LPWSTR serviceName;std::wstring wServiceName m_serviceName.toStdWString();serviceName wServiceName.data();// 打开服务控制管理器数据库SC_HANDLE schSCManager OpenSCManager(NULL, // 目标计算机的名称,NULL连接本地计算机上的服务控制管理器NULL, // 服务控制管理器数据库的名称NULL打开 SERVICES_ACTIVE_DATABASE 数据库SC_MANAGER_ALL_ACCESS // 所有权限);if (schSCManager NULL) {CloseServiceHandle(schSCManager);qDebug()服务开启时服务管理器打开失败GetLastError();return FALSE;}// 打开服务SC_HANDLE schService OpenService(schSCManager, // 服务控件管理器数据库的句柄serviceName, // 要打开的服务名SERVICE_ALL_ACCESS // 服务访问权限所有权限);if (schService NULL) {CloseServiceHandle(schService);CloseServiceHandle(schSCManager);qDebug()服务打开失败GetLastError();return FALSE;}else{qDebug()开启成功开启服务返回得结果schService;}lpsd (LPSERVICE_DESCRIPTIONW) LocalAlloc(LMEM_FIXED, cbBufSize);if( !QueryServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,NULL,0,dwBytesNeeded)){dwError GetLastError();if( ERROR_INSUFFICIENT_BUFFER dwError ){cbBufSize dwBytesNeeded;lpsd (LPSERVICE_DESCRIPTIONW) LocalAlloc(LMEM_FIXED, dwBytesNeeded);}else{qDebug()QueryServiceConfig2 failed:dwError;}}if (!QueryServiceConfig2(schService,SERVICE_CONFIG_DESCRIPTION,(LPBYTE) lpsd,cbBufSize,dwBytesNeeded) ){qDebug()QueryServiceConfig2 failed:GetLastError();}else{qDebug()QueryServiceConfig2 获取得描述信息:lpsd-lpDescription;qDebug()QueryServiceConfig2 获取得描述信息:QString::fromStdWString(lpsd-lpDescription);}LocalFree(lpsd);CloseServiceHandle(schService);CloseServiceHandle(schSCManager);return true;
}