一派护法 十九级 |
// 语言:C++ // 支持编译为Unicode版本,不支持ANSI版本 #include <string> #include <tchar.h> #include <Windows.h> #include <CommCtrl.h> #include <LM.h> #include <MsXml6.h> #include <ShlObj.h>
using namespace std; typedef basic_string<TCHAR> tstring;
#pragma comment(lib, "comctl32.lib") #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' language='*' publicKeyToken='6595b64144ccf1df'\"") #pragma comment(lib, "msxml6.lib") #pragma comment(lib, "Netapi32.lib")
BSTR bstr; VARIANT vbstr;
inline void alert(LPTSTR msg) { MessageBox(NULL, msg, TEXT("错误"), MB_ICONWARNING); }
void setNode(IXMLDOMDocument *pXMLDoc, IXMLDOMElement *pElem, LPWSTR name, LPCWSTR value) { bstr = SysAllocString(name); IXMLDOMElement *pNew; HRESULT hr = pXMLDoc->createElement(bstr, &pNew); SysFreeString(bstr); if (SUCCEEDED(hr)) { bstr = SysAllocString(value); hr = pNew->put_text(bstr); SysFreeString(bstr); if (SUCCEEDED(hr)) { hr = pElem->appendChild(pNew, NULL); pNew->Release(); } } if (FAILED(hr)) throw 0; }
void write(tstring folder, IXMLDOMDocument *pXMLDoc, IXMLDOMElement *pElem) { WIN32_FIND_DATA fd; HANDLE hFind = FindFirstFile((folder + TEXT("\\*")).c_str(), &fd); if (hFind == INVALID_HANDLE_VALUE) throw 1;
int err = -1; BSTR bstrLink = SysAllocString(L"link"); BSTR bstrFolder = SysAllocString(L"folder"); HRESULT hr; IXMLDOMElement *pFileElem = NULL; IXMLDOMElement *pFolderElem = NULL; IPersistFile *pFile = NULL; IShellLink *pLink = NULL; try { do { tstring filename = fd.cFileName; if (filename == TEXT(".") || filename == TEXT("..")) continue; tstring filepath = folder + TEXT("\\") + fd.cFileName; if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // 创建<folder> hr = pXMLDoc->createElement(bstrFolder, &pFolderElem); if (FAILED(hr)) throw 0; setNode(pXMLDoc, pFolderElem, L"name", filename.c_str()); write(filepath, pXMLDoc, pFolderElem); hr = pElem->appendChild(pFolderElem, NULL); if (FAILED(hr)) throw 0; pFolderElem->Release(); pFolderElem = NULL; continue; }
int len = filename.length(); if (filename.substr(len - 4) != TEXT(".lnk")) continue; // 跳过非快捷方式文件
// 创建<link> hr = pXMLDoc->createElement(bstrLink, &pFileElem); if (FAILED(hr)) throw 0;
setNode(pXMLDoc, pFileElem, L"name", filename.substr(0, len - 4).c_str()); hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pLink)); if (FAILED(hr)) throw 0; hr = pLink->QueryInterface(&pFile); if (FAILED(hr)) throw 0; bstr = SysAllocString(filepath.c_str()); hr = pFile->Load(bstr, STGM_READ); SysFreeString(bstr); if (FAILED(hr)) throw 0;
TCHAR szPath[MAX_PATH]; hr = pLink->GetPath(szPath, MAX_PATH, NULL, SLGP_RAWPATH); if (SUCCEEDED(hr) && szPath[0] != '\0') setNode(pXMLDoc, pFileElem, L"path", szPath);
TCHAR szDesc[INFOTIPSIZE]; hr = pLink->GetArguments(szDesc, INFOTIPSIZE); if (SUCCEEDED(hr) && szDesc[0] != '\0') setNode(pXMLDoc, pFileElem, L"arguments", szDesc);
hr = pLink->GetDescription(szDesc, INFOTIPSIZE); if (SUCCEEDED(hr) && szDesc[0] != '\0') setNode(pXMLDoc, pFileElem, L"description", szDesc);
WORD hotkey; hr = pLink->GetHotkey(&hotkey); if (SUCCEEDED(hr)) { _stprintf_s(szPath, TEXT("%d"), hotkey); setNode(pXMLDoc, pFileElem, L"hotkey", szPath); }
int icon; hr = pLink->GetIconLocation(szPath, MAX_PATH, &icon); if (SUCCEEDED(hr) && szPath[0] != '\0') { _stprintf_s(szDesc, TEXT("%d"), icon); setNode(pXMLDoc, pFileElem, L"icon", szPath); IXMLDOMNode *pLast; IXMLDOMElement *pLastElem; hr = pFileElem->get_lastChild(&pLast); if (SUCCEEDED(hr)) { hr = pLast->QueryInterface(&pLastElem); if (SUCCEEDED(hr)) { bstr = SysAllocString(L"index"); vbstr.bstrVal = SysAllocString(szDesc); pLastElem->setAttribute(bstr, vbstr); SysFreeString(bstr); SysFreeString(vbstr.bstrVal); pLastElem->Release(); } pLast->Release(); } }
int nCmdShow; // 这个就是WinMain函数里的第四个参数 hr = pLink->GetShowCmd(&nCmdShow); if (SUCCEEDED(hr)) { switch (nCmdShow) { case SW_SHOWNORMAL: setNode(pXMLDoc, pFileElem, L"show_cmd", L"SW_SHOWNORMAL"); break; case SW_SHOWMAXIMIZED: setNode(pXMLDoc, pFileElem, L"show_cmd", L"SW_SHOWMAXIMIZED"); break; case SW_SHOWMINIMIZED: setNode(pXMLDoc, pFileElem, L"show_cmd", L"SW_SHOWMINIMIZED"); break; default: setNode(pXMLDoc, pFileElem, L"show_cmd", L"Unknown"); break; } }
hr = pLink->GetWorkingDirectory(szPath, MAX_PATH); if (SUCCEEDED(hr) && szPath[0] != '\0') setNode(pXMLDoc, pFileElem, L"working_dir", szPath);
pFile->Release(); pFile = NULL; pLink->Release(); pLink = NULL;
hr = pElem->appendChild(pFileElem, NULL); if (FAILED(hr)) throw 0; } while (FindNextFile(hFind, &fd)); } catch (int i) { err = i; }
FindClose(hFind); SysFreeString(bstrLink); SysFreeString(bstrFolder); if (pFileElem != NULL) pFileElem->Release(); if (pFolderElem != NULL) pFolderElem->Release(); if (pLink != NULL) pLink->Release(); if (pFile != NULL) pFile->Release();
if (err != -1) throw err; }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { vbstr.vt = VT_BSTR; InitCommonControls();
TCHAR szFolder[MAX_PATH]; BOOL bResult = SHGetSpecialFolderPath(NULL, szFolder, CSIDL_COMMON_STARTMENU, FALSE); if (!bResult) { alert(TEXT("获取开始菜单文件夹路径失败!")); return 0; }
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (FAILED(hr)) { alert(TEXT("初始化COM失败!")); return 0; }
IXMLDOMDocument *pXMLDoc; hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pXMLDoc)); if (SUCCEEDED(hr)) { IXMLDOMElement *pRoot = NULL; IXMLDOMElement *pComm = NULL; IXMLDOMElement *pUser = NULL; IXMLDOMElement *pInfo = NULL; IXMLDOMProcessingInstruction *pProInstruction = NULL; try { /* 在文档中创建XML声明 */ bstr = SysAllocString(L"xml"); vbstr.bstrVal = SysAllocString(L"version=\"1.0\" encoding=\"utf-8\""); hr = pXMLDoc->createProcessingInstruction(bstr, vbstr.bstrVal, &pProInstruction); SysFreeString(bstr); SysFreeString(vbstr.bstrVal); if (SUCCEEDED(hr)) hr = pXMLDoc->appendChild(pProInstruction, NULL); if (FAILED(hr)) throw 0; pProInstruction->Release();
// 创建根节点<menu> bstr = SysAllocString(L"menu"); hr = pXMLDoc->createElement(bstr, &pRoot); SysFreeString(bstr); if (FAILED(hr)) throw 0;
// 创建<info> bstr = SysAllocString(L"info"); hr = pXMLDoc->createElement(bstr, &pInfo); SysFreeString(bstr); if (FAILED(hr)) throw 0;
// 工作组名 LPWSTR lpNameBuffer; NETSETUP_JOIN_STATUS bufferType; NET_API_STATUS nas = NetGetJoinInformation(NULL, &lpNameBuffer, &bufferType); if (nas == NERR_Success) { switch (bufferType) { case NetSetupUnknownStatus: setNode(pXMLDoc, pInfo, L"network", L"Unknown network status"); break; case NetSetupUnjoined: setNode(pXMLDoc, pInfo, L"network", L"Not joined to any workgroup or domain"); break; case NetSetupWorkgroupName: setNode(pXMLDoc, pInfo, L"workgroup", lpNameBuffer); break; case NetSetupDomainName: setNode(pXMLDoc, pInfo, L"domain", lpNameBuffer); break; } } NetApiBufferFree(lpNameBuffer);
// 计算机名 TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD n = MAX_COMPUTERNAME_LENGTH + 1; if (GetComputerName(szComputerName, &n)) setNode(pXMLDoc, pInfo, L"computer", szComputerName);
// 用户名 TCHAR szUserName[UNLEN + 1]; n = UNLEN + 1; if (GetUserName(szUserName, &n)) setNode(pXMLDoc, pInfo, L"user", szUserName);
// 添加<info> hr = pRoot->appendChild(pInfo, NULL); if (FAILED(hr)) throw 0;
// 创建<common> bstr = SysAllocString(L"common"); hr = pXMLDoc->createElement(bstr, &pComm); SysFreeString(bstr); if (FAILED(hr)) throw 0;
// 设置path属性 bstr = SysAllocString(L"path"); vbstr.bstrVal = SysAllocString(szFolder); hr = pComm->setAttribute(bstr, vbstr); SysFreeString(bstr); SysFreeString(vbstr.bstrVal); if (FAILED(hr)) throw 0;
write(szFolder, pXMLDoc, pComm);
// 添加<common> hr = pRoot->appendChild(pComm, NULL); if (FAILED(hr)) throw 0;
if (SHGetSpecialFolderPath(NULL, szFolder, CSIDL_STARTMENU, FALSE)) { // 创建<current_user> bstr = SysAllocString(L"current_user"); hr = pXMLDoc->createElement(bstr, &pUser); SysFreeString(bstr); if (FAILED(hr)) throw 0;
// 设置path属性 bstr = SysAllocString(L"path"); vbstr.bstrVal = SysAllocString(szFolder); hr = pUser->setAttribute(bstr, vbstr); SysFreeString(bstr); SysFreeString(vbstr.bstrVal); if (FAILED(hr)) throw 0;
write(szFolder, pXMLDoc, pUser);
// 添加<current_user> hr = pRoot->appendChild(pUser, NULL); if (FAILED(hr)) throw 0; }
// 添加根节点到文档中 hr = pXMLDoc->appendChild(pRoot, NULL); if (FAILED(hr)) throw 0;
// 保存文件 vbstr.bstrVal = SysAllocString(L"startmenu.xml"); hr = pXMLDoc->save(vbstr); SysFreeString(vbstr.bstrVal); if (FAILED(hr)) alert(TEXT("保存XML文件时出错!")); } catch (int i) { switch (i) { case 0: alert(TEXT("生成XML文档时出错!")); break; case 1: alert(TEXT("打开开始菜单文件夹时出错!")); break; } }
if (pRoot != NULL) pRoot->Release(); if (pComm != NULL) pComm->Release(); if (pUser != NULL) pUser->Release(); if (pInfo != NULL) pInfo->Release(); if (pProInstruction != NULL) pProInstruction->Release();
pXMLDoc->Release(); } else alert(TEXT("创建XML文档对象时失败!"));
CoUninitialize(); return 0; }
|