当前位置: 首页 > news >正文

windows创建服务:更新服务信息乱码问题(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, cbBufSize=0, 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;
}

相关文章:

windows创建服务:更新服务信息乱码问题(ChangeServiceConfig)

因为小项目需要创建windows服务&#xff0c;安装微软官方示例一切都挺顺利&#xff0c;代码运行后发现配置的信息在系统里显示乱码。打开注册表发现的确是乱码。这就排除软件读取得问题&#xff0c;而是调用ChangeServiceConfig系统函数写入时就发生了乱码。让我在网上查找了一…...

Spark 9:Spark 新特性

Spark 3.0 新特性 Adaptive Query Execution 自适应查询(SparkSQL) 由于缺乏或者不准确的数据统计信息(元数据)和对成本的错误估算(执行计划调度)导致生成的初始执行计划不理想&#xff0c;在Spark3.x版本提供Adaptive Query Execution自适应查询技术&#xff0c;通过在”运行…...

Angular+html+js前端加载生命周期

参考&#xff1a;document.readyState - Web API 接口参考 | MDN (mozilla.org) 第一步&#xff0c;JS生命周期第一步 文档加载中状态&#xff0c;document.readyState loading 第二步&#xff0c;JS生命周期第二步 可交互状态&#xff0c;document.readyState interacti…...

社区投稿| 以安全视角,深度剖析 Sui Staking 与 LSD

本篇技术研报由 MoveBit 研究团队的 Jason 撰写 #1 Sui Staking 介绍 1.1 Sui 网络概述 Sui 网络由一组独立的验证者运行&#xff0c;每个验证者在自己的机器或集群上运行独立的 Sui 软件实例。 Sui 采用委托权益证明&#xff08;DPoS&#xff09;来确定哪些验证者参与网络…...

AM@邻域@极限定义中的符号说明

文章目录 abstract邻域&#x1f47a;邻域中心和半径去心邻域 ϵ , δ \epsilon,\delta ϵ,δ的意义各种极限定义的共同点几何意义极限定义中的极限过程临界值 ϵ \epsilon ϵ的选取&#x1f47a; 概念辨析&#x1f47a;无限接近不同于越来越接近例例 越来越接近推不出无限接近 …...

论Oracle兼容性,我们需要做什么

作者介绍&#xff1a;王海峰&#xff0c;数据库系统架构师&#xff0c;YashanDB SQL开发负责人&#xff0c;10年以上数据库内核技术开发经验。 Oracle兼容性是目前国产数据库的关键任务之一&#xff0c;其直接影响到商业迁移的成本和竞争力。 我们经常发现&#xff0c;部分国产…...

你知道多号发圈的同时并延迟评论的方式吗?

你知道多号发圈的同时并延迟评论的方式吗&#xff1f; 其实很简单。 步骤1&#xff1a;编辑好朋友圈内容 步骤2&#xff1a;设置延迟评论 步骤3&#xff1a;选择多个号发圈 通过以上3个步骤&#xff0c;就可以实现多号发圈的同时并延迟评论。 在发布朋友圈前&#xff0c;只需要…...

【BugBounty】记一次XSS绕过

前言 最近一直在看国外的赏金平台&#xff0c;绕waf是真的难受, 记录一下绕过的场景。 初步测试 一开始尝试XSS&#xff0c;发现用户的输入在title中展示&#xff0c;那么一般来说就是看能否闭合&#xff0c;我们从下面图中可以看到&#xff0c;输入尖括号后被转成了实体。 …...

Linux文件目录结构详解:根目录和常见子目录介绍

文章目录 引言1. 什么是Linux文件目录结构2. Linux文件系统的重要性 根目录&#xff08;/&#xff09;2.1 根目录的作用和特点2.2 根目录下常见目录的介绍 /bin 目录3.1 /bin 目录的作用和内容3.2 常见的可执行命令示例 /etc 目录4.1 /etc 目录的作用和内容4.2 配置文件的存放位…...

知识付费小程序的推广与用户增长策略

在知识付费小程序开发完成后&#xff0c;推广和用户增长是关键的成功因素。本文将探讨一些推广策略和用户增长方法&#xff0c;并提供代码示例&#xff0c;帮助您在知识付费小程序中实施这些策略。 1. 社交媒体分享功能 在知识付费小程序中添加社交媒体分享功能&#xff0c;…...

微信小程序 获取当前屏幕的可见高宽度

很多时候我们做一下逻辑 需要用整个窗口的高度或宽度参与计算 而且很多时候我们js中拿到的单位都是px像素点 没办法和rpx同流合污 官方提供了wx.getSystemInfoSync() 可以获取到部分窗口信息 其中就包括了整个窗口的宽度和高度 wx.getSystemInfoSync().windowHeight 返回值为像…...

使用 Splashtop 驾驭未来媒体和娱乐

在当今时代&#xff0c;数字转型不再是可选项&#xff0c;而是必选项。如今&#xff0c;媒体与娱乐业处于关键时刻&#xff0c;正在错综复杂的创意、技术和远程协作迷宫之中摸索前进。过去几年发生的全球事件影响了我们的日常生活&#xff0c;不可逆转地改变了行业的运作方式&a…...

Tomcat项目启动报错

java.io.IOException: java.lang.ClassCastException: Cannot cast org.springframework.web.SpringServletContainerInitializer to javax.servlet.ServletContainerInitializer解决办法&#xff1a;可能Tomcat版本不对&#xff0c;使用7.0.90版本启动报错&#xff0c;使用8.0…...

offer

【录用通知书】 如何判断公司的好坏呢。 注意了&#xff0c;我们软件行业&#xff0c;技术管理类&#xff0c;技术类&#xff0c;产品类 好公司好企业基本都会给你说清楚&#xff0c;一项多少钱&#xff0c;加班多少钱&#xff0c;这样的 像这类公司的薪资结构复杂就要特别…...

漏洞复现--鸿运主动安全监控云平台任意文件下载

免责声明&#xff1a; **文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何…...

第二章 物理层 | 计算机网络(谢希仁 第八版)

文章目录 第二章 物理层2.1 物理层的基本概念2.2 数据通信的基础知识2.2.1 数据通信系统的模型2.2.2 有关信道的几个基本概念2.2.3 信道的极限容量 2.3 物理层下面的传输媒体2.3.1 导引型传输媒体2.3.2 非导引型传输媒体 2.4 信道复用技术2.4.1 频分复用、时分复用和统计时分复…...

路由高级特性

项目拓扑与项目需求 项目需求 某企业网络使用ospf和isis作为IGP协议实现内部网络的互联互通&#xff0c;区域规划和IP规划如图所示&#xff0c;现在要求实现如下需求&#xff1a; LSW1和AR1使用vlan10互联&#xff0c;与AR2使用vlan20互联&#xff0c;LSW1与LSW2、3、4之间使…...

【MySQL】数据库排查慢查询、死锁进程排查、预防以及解决方法

MySQL数据库排查慢查询、死锁进程及解决方法 一、排查慢查询 1.1检查慢查询日志是否开启 1.1.1使用命令检查是否开启慢查询日志: SHOW VARIABLES LIKE slow_query_log;如果是 Value 为 off 则并未开启 1.1.2开启并且查看慢查询日志: MySQL提供了慢查询日志功能,可以记录所…...

WSL2下的Docker配置和使用

在Windows的Linux子系统&#xff08;Windows Subsystem for Linux&#xff09;WSL2中安装、配置和使用 Docker&#xff0c;可以参考官方教程&#xff1a;WSL上的Docker远程容器入门. 重要步骤总结如下&#xff1a; 先决条件 确保你的计算机运行的是 Windows 10&#xff08;更…...

污水管网水位监测,管网水位监测仪守护城市污水管网运行

万宾科技&#xff1a;污水管网水位监测 近年来&#xff0c;城市化进程的加速使得污水管网建设愈发重要。然而&#xff0c;在管网运维中&#xff0c;水位监测一直以来都是一个令人头痛的难题。为了解决这一问题&#xff0c;万宾科技公司推出了管网水位监测仪EN200-D2&#xff0…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态

前言 在人工智能技术飞速发展的今天&#xff0c;深度学习与大模型技术已成为推动行业变革的核心驱动力&#xff0c;而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心&#xff0c;系统性地呈现了两部深度技术著作的精华&#xff1a;…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...