【技术·水】浅谈Dism++清理插件开发
前言
昨天我发布了NCleaner,一款Dism++清理插件(地址:http://bbs.pcbeta.com/viewthread-1692182-1-1.html)
有些人想要我开源NCleaner;我只能说很遗憾,鉴于国内环境,是不可能的。我就说个真实故事吧(其实很悲哀)
曾经,一位大牛写了一个充满了黑科技的软件,在论坛发布并公布了源代码
某天,那位大牛发现某些人修改他的源代码用于商业用途,更可气的是某些人只修改了软件的名字
最终,那位大牛改掉了他的软件名,从此再也不公布主程序源代码
那个软件就是Dism管理器,即Dism++前身
虽然NCleaner闭源,但是我可以写一篇Dism++插件开发教程作为补偿(笑)
虽然我不能保证该教程写的多么生动;但是我会尽力(笑)
Dism++,我只能说这软件真的是非常强大(这只是我个人看法);至于可靠性,你只要不作死开启专家模式那就没问题(笑)
说到Dism++插件开发,其实以前作者提供过SDK(但是很长时间就再也没提供过);上次和作者谈了谈我想开发插件的想法(希望作者可以提供SDK);最终如愿以偿,并发布了NCleaner(用游戏相关话语来说,我也是过了一周目的人)
开发环境
1. Dism++ 10.1.5.3及以后版本的Dism++(没有Dism++开发Dism++插件是不可能的)
2. 一个可以编译dll的C++编译器,我推荐使用Visual Studio 2015
3. 如果可以的话,最好安装Windows SDK 10.0.10586
Dism++清理插件相关内容科普
首先说下Dism++清理插件函数定义(参考Dism++帮助文档.pdf 68页)
//一个清理插件函数定义
HRESULT WINAPI CleanupPlugin(
_In_ DismSession Session,
_Reserved_ DWORD Flags,
_In_opt_ UINT64 *CleanUpSpace,
_In_ DismCallBack CallBack,
_In_ LPVOID UserData);
DismSession Session
映像会话,可以使用此获取映像的各种信息(可以看作映像会话的句柄)
DWORD Flags
保留,Dism++现在不使用此参数,请忽略
UINT64 *CleanUpSpace
如果 CleanUpSpace 为空,那么函数需要执行清理。
如果不为空,说明仅要预估可清理的空间。最后将预估大小用此变量返回
DismCallBack CallBack
Dism++清理回调函数,用于展示进度,文件路径等信息。
如果此参数为 NULL,则表示没有回调。
回调函数定义参考下一段介绍
LPVOID UserData
回调函数的 UserData 部分,请务必传入 CallBack 中。
返回值: 如果函数执行成功,请返回 S_OK,其他任何值都表示错误
回调函数定义
typedef DWORD(WINAPI *DismCallBack)(
DWORD dwMessageId,
WPARAM wParam,
LPARAM lParam,
PVOID UserData);
回调函数支持以下消息:
DISM_MSG_PROGRESS – 用于反馈处理进度
wParam =当前完成百分比
lParam = 0
DISM_MSG_PROCESS – 用于在状态栏中展示正在处理的文件路径
wParam = (PWSTR) pszFullPath
lParam = 0
DISM_MGS_RemoveInfo
报告 UI 需要删除的文件,此消息仅扫描时可用,清理时将无视此消息
wParam = 0
lParam = (LPCWSTR) 需要删除的文件路径
Dism++收到此消息后,会将文件路径展示在详细信息中。
我经常使用的Dism++ API介绍(希望对其他人有用)
HRESULT WINAPI DismGetSystemInfoBySession(
DismSession Session,
DismSystem** Info);
该API作用是获取当前映像信息;你会得到DismSystem结构的指针(看Dism++作者对于该结构的说明,我想你们应该都能理解)
HRESULT WINAPI DismFreeMemory(void* pStruct);
切记通过Dism++获得的结构指针需要用该API释放
HRESULT WINAPI DismRegOpenKeyEx(
DismSession Session,
HKEY hKey,
LPCWSTR lpSubKey,
REGSAM samDesired,
PHKEY phkResult);
获取注册表键值,用法类似RegOpenKeyEx
HRESULT WINAPI DismWriteLog(
DWORD LogLevel,
LPCWSTR LogName,
LPCWSTR LogValue);
写入日志,LogLevel定义如下,LogName是日志类别,LogValue是日志内容
DismLogLevelSilent 不输出任何信息
DismLogLevelFailure 仅错误
DismLogLevelWarning 错误和警告
DismLogLevelInformation 错误、警告和信息
DismLogLevelDebug 以上所有内容和调试输出
插件开发注意事项
1. Dism++基于CBS,而CBS是一个COM组件;所以在启动时会自动进行COM初始化;你不需要在清理插件函数中执行COM初始化;切记不要在清理插件函数中调用COM反初始化,否则后果我和Dism++的作者们都不敢想(当然不敢试)
2. 注意DismSystem结构的RootPath的路径类似"C:","D:\Image"这样的(在写文件操作代码时需要注意)
3. Dism++的展开环境变量API在离线下会受限
4. Dism++的打开注册表API不支持打开离线映像的HKEY_USERS(Dism++旧版本支持;只是作者在某个版本移除了);HKEY_CURRENT_USER打开的是Default User的注册表
5. 只有返回S_OK,才代表Dism++ API正确执行
插件开发教程
配置好环境,打开Visual Studio;首先新建一个Win32动态链接库项目
接着把Dism++SDK(Dism++目录\Dism++SDK目录中的内容)复制到你的项目目录,并加入你的解决方案
然后你可以在cpp文件中根据前文内容编写你要编写的代码(下面举个例子)
#include <Windows.h>
#include "Dism++API.h"
#include "Plugin.h"
#ifdef _AMD64_
#pragma comment(lib,"Dism++x64.lib")
#else
#pragma comment(lib,"Dism++x86.lib")
#endif
// Dism++清理插件开发入门
HRESULT WINAPI TestCleanup(
_In_ DismSession Session,
_Reserved_ DWORD Flags,
_In_ UINT64 *CleanUpSpace,
_In_ DismCallBack CallBack,
_In_ LPVOID UserData)
{
MessageBoxW(nullptr, L"Hello Dism++", L"HelloWorld", MB_ICONINFORMATION);
return S_OK;
}
顺便你需要建立一个def文件导出你的符号(同样举个例子)
LIBRARY
EXPORTS
TestCleanup
还有你需要编写Dism++的插件配置文件(需要命名为Custom.xml,下面举个例子)
<?xml version="1.0" encoding="utf-8"?>
<Data>
<CleanCollection4>
<Item Name="清理项目名" Level="2">
<Discription>清理项目描述 </Discription>
<Warning>警告对话框要显示的内容</Warning>
<Group>清理项目所属组</Group>
<ScanCollection>
<Scan Type="Custom">
<Activate>
<Custom ProcName="插件dll对应的导出符号"/>
</Activate>
</Scan>
</ScanCollection>
</Item>
</CleanCollection4>
</Data>
和Dism++插件信息文件(需要命名为Info.xml)
<?xml version="1.0" encoding="utf-8"?>
<Data>
<Plugin>
<Name>插件名称</Name>
<Version>填写插件的版本号,例如1.0.0.0</Version>
</Plugin>
<Languages>
<zh>
<FriendlyName>插件名称(中文)</FriendlyName>
<Decription>插件注释(中文)</Decription>
</zh>
<en>
<FriendlyName>插件名称(英文)</FriendlyName>
<Decription>插件注释(英文)</Decription>
</en>
</Languages>
</Data>
编译
64位dll需要命名为Plugin.amd64.dll;32位dll需要命名为Plugin.x86.dll
Plugin.amd64.dll , Plugin.x86.dll , Custom.xml , Info.xml这四个文件需要放在一个以 [插件名]_[发布者名称Base64加密密文;发布者名称要求16个字符]目录中,并把该目录复制入Dism++目录\Config\Plugin目录即可
然后开启Dism++就可以进行调试了(VisualStudio->调试->附加到进程)
Demo项目下载(要求VS2015)
http://pan.baidu.com/s/1o8znY7w
结语
最后我得提醒想开发Dism++清理插件的开发者,虽然插件写起来是容易的,但要注意的细节是很多(写本教程时,楼主的体会越发深刻)
如果想获取更多信息,建议加入Dism++官方群(200783396)讨论
毛利
【技术·水】浅谈Dism++清理插件开发的更多相关文章
- 技术分析 | 浅谈在MySQL体系下SQL语句是如何在系统中执行的及可能遇到的问题
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 SQL语句大家并不陌生,但某种程度上来看,我们只是知道了这条语句是什么功能,它可 ...
- 技术分享 | 浅谈mysql语法解析调试方法
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 本文向您介绍一种利用mysql解析器和bison的调试选项进行sql语法解析跟踪 ...
- 技术分享 | 浅谈MySQL闪回的实现
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 1.闪回实现原理 2.binlog文件格式初探 3.闪回实现过程 1.闪回实现原 ...
- 防止apk反编译的技术分析浅谈--内存修改器篇
声明: 1.本帖转载自http://jingyan.baidu.com/article/a24b33cd509eb719fe002b94.html,仅供自用,勿喷 Apk反编译修改器有很多.拿其中的比 ...
- 视频基础知识:浅谈视频会议中H.264编码标准的技术发展
浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...
- 搞懂分布式技术21:浅谈分布式消息技术 Kafka
搞懂分布式技术21:浅谈分布式消息技术 Kafka 浅谈分布式消息技术 Kafka 本文主要介绍了这几部分内容: 1基本介绍和架构概览 2kafka事务传输的特点 3kafka的消息存储格式:topi ...
- 【转】.NET(C#):浅谈程序集清单资源和RESX资源 关于单元测试的思考--Asp.Net Core单元测试最佳实践 封装自己的dapper lambda扩展-设计篇 编写自己的dapper lambda扩展-使用篇 正确理解CAP定理 Quartz.NET的使用(附源码) 整理自己的.net工具库 GC的前世与今生 Visual Studio Package 插件开发之自动生
[转].NET(C#):浅谈程序集清单资源和RESX资源 目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...
- 浅谈Hybrid技术的设计与实现
前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发 ...
- (转)浅谈Hybrid技术的设计与实现
转载地址:https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hyb ...
随机推荐
- HW2.20
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- POJ3641-Pseudoprime numbers(快速幂取模)
题目大意 判断一个数是否是伪素数 题解 赤果果的快速幂取模.... 代码: #include<iostream> #include<cmath> using namespace ...
- What's the difference between all the Selection Segues
relationship -A "relationship" segue is the segue between a container view controller and ...
- 高密度Java应用部署的一些实践
传统的Java应用部署模式,一般遵循“硬件->操作系统->JVM->Java应用”这种自底向上的部署结构,其中JEE应用可以细化为“硬件->操作系统->JVM->J ...
- local storage 简单应用‘’记住密码’
前些时候一直用cookie等来进行登录页面记住面膜操作,但是由于其存储容量小等缘故,所以后来转向local storage,原理为:当用户勾选记住密码时,local storage 存储用户名密码同时 ...
- 【转】bootbox自定义dialog、confirm、alert样式,以及基本设置方法setDefaults中可用参数
<html> <head> <meta charset="utf-8"> <meta name="viewport" ...
- 清理Win8.1更新冗余的批处理代码
以下为批处理文件内容,复制到文本文件,另存为.bat文件,以管理员方式运行即可. @echo off title 清理Win8.1更新冗余 color 2e echo 提示:本程序可能需要以管理员方式 ...
- asp.net Mvc+bootstarp+esayUI+EF 框架(一)
"框架" 这两个字从通俗的意义来讲就是提高复用性,解耦类之间的关系和方便开发人员开发. 使用的技术也是大家基本现在都用过的,而这个系类我所要讲的内容是什么呢? 框架的基本 ...
- android安全问题(八)伪造短信(利用原生android4.0漏洞)
导读:本文利用android4.0的一个原生漏洞来伪造短信.无须声明任何权限即可伪造发送方为任何号码的短信给用户. android4.0发布已经是很久很久很久很久以前的事情了,这个漏洞早就报了出来,之 ...
- Android开发环境搭建(windows OS)之补充
这几天搭建了个安卓开发环境,也想玩玩安卓开发.在查询CSDN,CNBLOG,视频网站之后终于把开发环境搭建起来了,发现所有的指导都比较离散,比如有些只说安装方法,有些只说下载方法.本文来个集大成,算是 ...