当我们安装一款软件的时候,这款软件的一些快捷方式可能被设置到开始菜单的“常用应用”区域。但是,如果是“卸载”快捷方式被“钉”到该区域,就会造成非常不好的体验。毕竟把“卸载”接口暴露得如此醒目,如同把该款软件的地狱大门暴露出来。(转载请指明出于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 |
从后缀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=a3UL0bMbmzzINfomfkCgTHyUOQDwBk83WkEjcgH6gZdvproZg7OTcXkt6G3oLLFpZnBXwXWhFWeGhqXBN8Tuhq std::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 DEBUG std::wstring wstrOutput = wstrValueName; wstrOutput.append( WCHAR(‘\n‘), 1); OutputDebugStringW(wstrOutput.c_str()); #endif return 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 ) { // Suc bSuc = 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上,使用相同的方法应该可以得出注册表路径。
一种将快捷方式从开始菜单“常用应用”的中去除的方法,布布扣,bubuko.com
原文:http://blog.csdn.net/breaksoftware/article/details/23127589