一种将快捷方式从开始菜单“常用应用”的中去除的方法
? ? ? ? 當(dāng)我們安裝一款軟件的時(shí)候,這款軟件的一些快捷方式可能被設(shè)置到開始菜單的“常用應(yīng)用”區(qū)域。但是,如果是“卸載”快捷方式被“釘”到該區(qū)域,就會(huì)造成非常不好的體驗(yàn)。畢竟把“卸載”接口暴露得如此醒目,如同把該款軟件的地獄大門暴露出來。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)
? ? ? ??如下圖,python就將卸載程序放到了“常用區(qū)域”。從而會(huì)導(dǎo)致windows會(huì)將該快捷方式放到“常用應(yīng)用”區(qū)域。
? ? ? ? 一種解決方案就是,不將“卸載”快捷方式放到開始菜單的“普通區(qū)域”。很多應(yīng)用都是使用這種方式。
? ? ? ? 另一種就是如何將該項(xiàng)從“常用應(yīng)用”區(qū)域刪除。本文就是講解這套方案的研究和分析。
? ? ? ? 首先,我們使用RegSnap抓取一次注冊(cè)表快照。然后在”常用應(yīng)用“區(qū)域刪除notepad++的啟動(dòng)快捷方式,再生成一次快照。對(duì)比兩次快照。我們可以得出如下結(jié)果:
?
| 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 |
? ? ? ? 從對(duì)比圖中,我們可以看到一個(gè)叫Abgrcnq++.yax被刪除了。這個(gè)是個(gè)非常有意思的名字,我們可以看出來,這個(gè)名字明顯是被加密的,但是加號(hào)和點(diǎn)號(hào)沒有被加密。我又觀察了其他的鍵(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\Count下)
? ? ? ? 從后綴rkr可以想象,這個(gè)可能是exe的加密結(jié)果。后來我做了下計(jì)算,發(fā)現(xiàn)字符間存在13的差值。后來才知道這個(gè)就是所謂的ROT13置換轉(zhuǎn)換碼。該算法的詳細(xì)介紹可以見
http://baike.baidu.com/link?url=a3UL0bMbmzzINfomfkCgTHyUOQDwBk83WkEjcgH6gZdvproZg7OTcXkt6G3oLLFpZnBXwXWhFWeGhqXBN8Tuhq
? ? ? ? 后來,我又做了一個(gè)實(shí)驗(yàn)——?jiǎng)h除了HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}\Count的一個(gè)鍵,該鍵對(duì)應(yīng)的快捷方式在開始菜單的”常用應(yīng)用“區(qū)域。發(fā)現(xiàn),該鍵被刪除后,該快捷方式就消失了。
? ? ? ? 以下是測(cè)試代碼:
?
// RegExplorerUserAssist.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。
//#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安全衛(wèi)士\\360安全衛(wèi)士.lnk");}return 0;
}
? ? ? ? 有一點(diǎn)需要說明——XP下不是該注冊(cè)表路徑。如果想將方案移植到XP上,使用相同的方法應(yīng)該可以得出注冊(cè)表路徑。
?
最后附上工程代碼。
總結(jié)
以上是生活随笔為你收集整理的一种将快捷方式从开始菜单“常用应用”的中去除的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一种清除windows通知区域“僵尸”图
- 下一篇: 使用WinHttp接口实现HTTP协议G