当我们安装一款软件的时候,这款软件的一些快捷方式可能被设置到开始菜单的“常用应用”区域。但是,如果是“卸载”快捷方式被“钉”到该区域,就会造成非常不好的体验。毕竟把“卸载”接口暴露得如此醒目,如同把该款软件的地狱大门暴露出来。(转载请指明出于breaksoftware的csdn博客)

如下图,python就将卸载程序放到了“常用区域”。从而会导致windows会将该快捷方式放到“常用应用”区域。

一种解决方案就是,不将“卸载”快捷方式放到开始菜单的“普通区域”。很多应用都是使用这种方式。

另一种就是如何将该项从“常用应用”区域删除。本文就是讲解这套方案的研究和分析。

首先,我们使用RegSnap抓取一次注册表快照。然后在”常用应用“区域删除notepad++的启动快捷方式,再生成一次快照。对比两次快照。我们可以得出如下结果:

Deleted keys
HKEY_USERS\S-1-5-21-3689171631-189274284-2341753515-176562\Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs\70
HKEY_USERS\S-1-5-21-3689171631-189274284-2341753515-176562\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\Count\{0139Q44R-6NSR-49S2-8690-3QNSPNR6SSO8}\Abgrcnq++\Abgrcnq++.yax

从对比图中,我们可以看到一个叫Abgrcnq++.yax被删除了。这个是个非常有意思的名字,我们可以看出来,这个名字明显是被加密的,但是加号和点号没有被加密。我又观察了其他的键(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\Count下)

从后缀rkr可以想象,这个可能是exe的加密结果。后来我做了下计算,发现字符间存在13的差值。后来才知道这个就是所谓的ROT13置换转换码。该算法的详细介绍可以见

http://baike.baidu.com/link?url=a3UL0bMbmzzINfomfkCgTHyUOQDwBk83WkEjcgH6gZdvproZg7OTcXkt6G3oLLFpZnBXwXWhFWeGhqXBN8Tuhq

后来,我又做了一个实验——删除了HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\Count的一个键,该键对应的快捷方式在开始菜单的”常用应用“区域。发现,该键被删除后,该快捷方式就消失了。

以下是测试代码:

// RegExplorerUserAssist.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"#include <windows.h>
#include <string>/*
Registry value names are limited to 32,767 bytes.
The ANSI version of this function treats this parameter as a SHORT value.
Therefore, if you specify a value greater than 32,767 bytes, there is an overflow and the function may return ERROR_MORE_DATA.
*/
#define MAX_VALUE_NAME 16383// http://baike.baidu.com/link?url=a3UL0bMbmzzINfomfkCgTHyUOQDwBk83WkEjcgH6gZdvproZg7OTcXkt6G3oLLFpZnBXwXWhFWeGhqXBN8Tuhqstd::wstring ConvertData( LPCWSTR lpBuffer, DWORD dwLength ) {std::wstring wstrValueName;for ( DWORD dwIndex = 0; dwIndex < dwLength; dwIndex++ ) {WCHAR wchSingle = *( lpBuffer + dwIndex );unsigned char ucsa = LOBYTE(WCHAR('a'));unsigned char ucsz = LOBYTE(WCHAR('z'));unsigned char ucbA = LOBYTE(WCHAR('A'));unsigned char ucbZ = LOBYTE(WCHAR('Z'));if ( ( WCHAR('a') <= wchSingle && WCHAR('z') >= wchSingle ) || ( WCHAR('A') <= wchSingle && WCHAR('Z') >= wchSingle )  ) {unsigned char uc = LOBYTE(wchSingle);if ( ucsa <= uc && ucsz >= uc ) {uc = ( ( uc + 13 ) > ucsz  ) ? uc - 13 : uc + 13;}else if ( ucbA <= uc && ucbZ >= uc ) {uc = ( ( uc + 13 ) > ucbZ  ) ? uc - 13 : uc + 13;}wchSingle = WCHAR(MAKELONG(uc,0));}wstrValueName.append( &wchSingle, 1 );}#ifdef DEBUGstd::wstring wstrOutput = wstrValueName;wstrOutput.append( WCHAR('\n'), 1);OutputDebugStringW(wstrOutput.c_str());
#endifreturn wstrValueName;
}BOOL DeleteValue(HKEY hKey, const std::wstring& wstrSubString)
{ WCHAR wchValueName[MAX_VALUE_NAME] = {0};LPWSTR lpValueNameBuffer = wchValueName;DWORD dwValueNameBufferLength = ARRAYSIZE(wchValueName);BOOL bSuc = FALSE;do {DWORD    dwValuesCount = 0;              // number of values for key DWORD    dwMaxValueNameLen = 0;          // longest value name // Get the class name and the value count. LONG lretCode = RegQueryInfoKey( hKey,NULL, NULL, NULL, NULL, NULL, NULL, &dwValuesCount, &dwMaxValueNameLen, NULL, NULL, NULL );if ( ERROR_SUCCESS != lretCode ) {break;}// Enumerate the key values.if ( 0 != dwValuesCount) {for ( DWORD dwIndex = 0; dwIndex < dwValuesCount; dwIndex++ )  { DWORD dwValueNameInlineLength = dwValueNameBufferLength;wmemset( lpValueNameBuffer, 0, dwValueNameInlineLength);lretCode = RegEnumValue(hKey, dwIndex, lpValueNameBuffer, &dwValueNameInlineLength, NULL, NULL, NULL, NULL);if ( ERROR_NO_MORE_ITEMS == lretCode ) { // SucbSuc = TRUE;break;} if ( ERROR_MORE_DATA == lretCode ) {if ( wchValueName != lpValueNameBuffer ) {if ( NULL != lpValueNameBuffer ) {delete [] lpValueNameBuffer;lpValueNameBuffer = NULL;}}lpValueNameBuffer = new WCHAR[dwValueNameInlineLength];dwValueNameBufferLength = dwValueNameInlineLength;dwIndex--;}if ( ERROR_SUCCESS == lretCode ) {std::wstring wstrValueName = ConvertData( lpValueNameBuffer, dwValueNameInlineLength );if ( std::wstring::npos == wstrValueName.find( wstrSubString.c_str() ) ) {continue;}else {bSuc = RegDeleteValue( hKey, wstrValueName.c_str() );break;}}}}} while (0);if ( lpValueNameBuffer != wchValueName ) {delete [] lpValueNameBuffer;lpValueNameBuffer = NULL;}return bSuc;
}int _tmain(int argc, _TCHAR* argv[])
{HKEY hTestKey;if( RegOpenKeyEx( HKEY_CURRENT_USER,TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\\Count"),0,KEY_READ,&hTestKey) == ERROR_SUCCESS){DeleteValue(hTestKey, L"\\360安全中心\\360安全卫士\\360安全卫士.lnk");}return 0;
}

有一点需要说明——XP下不是该注册表路径。如果想将方案移植到XP上,使用相同的方法应该可以得出注册表路径。

最后附上工程代码。

一种将快捷方式从开始菜单“常用应用”的中去除的方法相关推荐

  1. excel多级表头存入mysql_一种多个多层表头的表格在数据库中的存储及其访问方法与流程...

    技术领域: 本发明涉及一种多个多层表头的表格在数据库中的存储方法. 背景技术: :在各个领域,长期以来都会产生和积累大量手绘的.印刷的或EXCEL格式保存的表格数据,将这些表格数据录入到数据库系统中存 ...

  2. 几种常用编程语言的编程思想和方法 转

    搞软件的人,编程语言的掌握是基本功,如果单单是学习语法,最慢的一周之内也应该可以搞定(个人认为 语法层面c++是最复杂的).不幸的是,软件的本质是逻辑,解决方案的设计是要借助某种解决问题或编程的思想的 ...

  3. Windows Mobile打包时增加快捷方式到开始菜单的方法

    背景 在进行Windows Mobile部署程序开发时,默认是不生成开始菜单的快捷方式.如果想把程序快捷方式增加到开始菜单下,需要手工增加安装项. 简述 本文讲述开发Windows Mobile部署项 ...

  4. OpenCV学习笔记(二):3种常用访问图像中像素的方式

    OpenCV学习笔记(二):3种常用访问图像中像素的方式 #include <opencv2/opencv.hpp>using namespace cv; using namespace ...

  5. 几种常用的产生负电源的方法

    电源电路是电路设计的重要环节,一般情况下,单电源能实现功能的用单电源就行,可选的方案很多,DC-DC.LDO等芯片很多.有时候,单电源无法满足需求时,就必须用到负电源. 今天就来介绍几种常用的负电源产 ...

  6. excel函数去重_Excel 2010中去除重复项的几种常用技巧

    在工作中使用Excel 2010时,经常会有需要在对原始记录清单进行整理时,剔除其中一些重复项.接下来本文就来讲解下Excel 2010中去除重复项的几种常用技巧. 所谓的重复项,通常是指在Excel ...

  7. 8种适用于不同机器学习问题的常用数据集

    要找到一定特定的数据集可以解决各种机器学习问题,是一件很难的事情.越来越多企业或研究机构将自己的数据集公开,已经成为全球的趋势,这也将有助于大家进行更多研究. 近期,亚马逊高级技术顾问 Will Ba ...

  8. 五种常见的加密方式及常用的加解密工具

    如果你是互联网公司的信息安全从业者,那么你可能会经常需要处理撞库事件,撞库是黑客的无聊"恶作剧".黑客收集已经在互联网上泄露的用户和密码信息,生成对应的字典表,并尝试批量登录其他网 ...

  9. Ajax的五种接收响应头消息(常用)

    学习本文你得先了解php与Ajax 我的PHP初探 Ajax的了解与应用 五种响应头消息 1. textt/plain 字符串 服务端的消息响应头:header("Content-Type: ...

最新文章

  1. Alibaba Cluster Data 开放下载:270GB 数据揭秘你不知道的阿里巴巴数据中心
  2. openstack之horizon源码分析之二
  3. bootstrap easyUI 的选型
  4. 哈佛大学计算机科学专,哈佛大学计算机科学专业
  5. M1 macbook值得购买吗?关于M1芯片macbook的三点购买建议
  6. 2020各大网站rss订阅源地址_2020-20-18——DJANGO复习
  7. 显示编译代码时长的demo
  8. 2021-08-03 SELECT简单查询
  9. 开源的东西,只是用来参考学习,要商用路途遥远
  10. python 欧姆龙plc通信_电脑与欧姆龙plc通过网络通信
  11. CAD批量打图精灵自动识别纸张大小
  12. [tensorflow] 数字标签转化为one-hot形式的tensor
  13. OpenCV (c++)使用KDTree时,得到正确结果后报Segmentation fault (core dumped)
  14. 后台录屏、应用外录屏、跨应用录屏、直播屏幕、录屏扩展(ios)
  15. 陈文俊 计算机科学,2019年丘成桐中学科学奖总决赛获奖结果揭晓!
  16. Smart3D系列教程1之《浅谈无人机倾斜摄影建模的原理与方法》
  17. Re28:读论文 CECP Charge Prediction by Constitutive Elements Matching of Crimes
  18. pta 哥尼斯堡的“七桥问题”
  19. 虚拟机(Ubuntu18.04版本)中文字体乱码或混乱的一种解决方案
  20. 技术培训 | 青云QingCloud 对象存储应用与实践

热门文章

  1. 快来学习Redis 分布式锁的背后原理
  2. postgresql Insert插入的几个报错
  3. end-to-end 的神经网络
  4. ~~~端午安康~~~
  5. knn 进行手写数字识别
  6. LeetCode刷题记录13——705. Design HashSet(easy)
  7. 【禅模式】如何进入极度专注的心流状态,让前端开发能力发挥到最大?设置VSCode禅模式快捷键Alt+F切换全屏,适合演示代码使用
  8. ATS中的RAM缓存简介
  9. C++的STL 栈 实现四则运算
  10. 计算机网络面试题(一)