📄 jelinstaller.cpp
字号:
/* * JELInstaller.cpp - part of jEditLauncher package * Copyright (C) 2001 John Gellene * jgellene@nyc.rr.com * * Notwithstanding the terms of the General Public License, the author grants * permission to compile and link object code generated by the compilation of * this program with object code and libraries that are not subject to the * GNU General Public License, provided that the executable output of such * compilation shall be distributed with source code on substantially the * same basis as the jEditLauncher package of which this program is a part. * By way of example, a distribution would satisfy this condition if it * included a working makefile for any freely available make utility that * runs on the Windows family of operating systems. This condition does not * require a licensee of this software to distribute any proprietary software * (including header files and libraries) that is licensed under terms * prohibiting redistribution to third parties. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Id: JELInstaller.cpp,v 1.11 2001/09/07 15:20:23 jgellene Exp $ */#include "stdafx.h"#include <string.h>#include "InstallData.h"#include "DeferFileOps.h"#include "CtxMenuDlg.h"#include "StringPtr.h"#include "InstallerLog.h"#include "JELRegInstaller.h"#include "JELInstaller.h"#include <stdlib.h> // for itoa in debug/* Implementation of JELFileInstaller */JELFileInstaller::JELFileInstaller(const InstallData *ptrData, Installer *ptrOwner) : pData(ptrData), pOwner(ptrOwner), pDFO(0), bRebootNeeded(false) {}JELFileInstaller::~JELFileInstaller(){ delete pDFO;}// if returns S_FALSE; set bRebootRequired to true// if returns S_OK set strInstallPath to strInstallFinalPathHRESULT JELFileInstaller::Install(){ bRebootNeeded = false; DWORD dwError = 0; HRESULT hr; if(pData->nIndexOverwrittenVer != -1) { if(pData->strInstallPath.Compare(pData->strOldPath) == 0) { InstallerLog::Log("Shell extension is up to date: no copying required.\n"); // nothing to do here return S_OK; } // do copy/overwrite InstallerLog::Log("Overwriting shell extension with new version.\n"); if(!CopyFile(pData->strInstallPath, pData->strInstallFinalPath, FALSE)) { dwError = GetLastError(); if(ERROR_SHARING_VIOLATION != dwError) { InstallerLog::Log("Overwrite failed: unspecified error.\n"); hr = E_FAIL; } else { InstallerLog::Log("Overwrite failed: reboot required.\n"); if(pData->bIsWinNT) pDFO = new DeferFileOpsNT; else pDFO = new DeferFileOps95; pDFO->Read(); pDFO->Add(pData->strInstallFinalPath, pData->strInstallPath); if(FAILED(pDFO->Write())) { InstallerLog::Log("Could not set up file copy after reboot.\n"); hr = E_FAIL; } else { bRebootNeeded = true; hr = S_FALSE; } delete pDFO; } } else hr = S_OK; } else { // do move/delete InstallerLog::Log("Renaming shell extension to jeshlstb.dll.\n"); if(!MoveFile(pData->strInstallPath, pData->strInstallFinalPath)) { dwError = GetLastError(); if(ERROR_SHARING_VIOLATION != dwError) { InstallerLog::Log("Rename failed: error code %d.\n", dwError); hr = E_FAIL; } else { InstallerLog::Log("Rename failed: reboot required.\n"); if(pData->bIsWinNT) pDFO = new DeferFileOpsNT; else pDFO = new DeferFileOps95; pDFO->Read(); pDFO->Add(pData->strInstallFinalPath, pData->strInstallPath); if(FAILED(pDFO->Write())) { InstallerLog::Log("Could not set up file rename after reboot.\n"); hr = E_FAIL; } else { bRebootNeeded = true; hr = S_FALSE; } delete pDFO; } } else { InstallerLog::Log("Shell extension installed; no reboot required.\n"); hr = S_OK; } } return hr;}HRESULT JELFileInstaller::Uninstall(){ bRebootNeeded = false; WIN32_DIR_WALK finddata; lstrcpy(finddata.cDirMask, pData->strInstallDir); lstrcat(finddata.cDirMask, _T("\\*.*")); if(pData->bIsWinNT) { pDFO = new DeferFileOpsNT(); } else { pDFO = new DeferFileOps95(); } pDFO->Read(); EmptyDirectory(&finddata, pDFO); // remove parent directory if(!RemoveDirectory(pData->strInstallDir)) { bRebootNeeded = true; pDFO->Add(0, pData->strInstallDir); } if(bRebootNeeded) { pDFO->Write(); } delete pDFO; return (bRebootNeeded ? S_FALSE : S_OK);}void JELFileInstaller::EmptyDirectory(PWIN32_DIR_WALK pFinddata, DeferFileOps *pDFO){ TCHAR *pDirMarker = pFinddata->cDirMask + lstrlen(pFinddata->cDirMask) - 4; HANDLE findHandle = FindFirstFile(pFinddata->cDirMask, pFinddata); if(findHandle == INVALID_HANDLE_VALUE) return; BOOL findResult = TRUE; while (findResult) { if(pFinddata->dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { // call MakeChildMask/MakeParentMask // to recurse into and delete child directories int len = lstrlen(pFinddata->cFileName) - 1; if(pFinddata->cFileName[len] != _T('.')) { MakeChildMask(pFinddata->cDirMask, pFinddata->cFileName); EmptyDirectory(pFinddata, pDFO); TCHAR *pChildDirMarker = pFinddata->cDirMask + lstrlen(pFinddata->cDirMask) - 4; *pChildDirMarker = 0; if(!RemoveDirectory(pFinddata->cDirMask)) { bRebootNeeded = true; pDFO->Add(0, pFinddata->cDirMask); } *pChildDirMarker = _T('\\'); MakeParentMask(pFinddata->cDirMask); } } else { *(pDirMarker + 1) = 0; lstrcat(pDirMarker, pFinddata->cFileName); if(!DeleteFile(pFinddata->cDirMask)) { bRebootNeeded = true; pDFO->Add(0, pFinddata->cDirMask); } *(pDirMarker + 1) = 0; lstrcat(pFinddata->cDirMask, _T("*.*")); } findResult = FindNextFile(findHandle, pFinddata); } FindClose(findHandle);}bool JELFileInstaller::MakeParentMask(LPTSTR lpszMask){ if(lpszMask == 0) return false; int nIndexLastNoMask = lstrlen(lpszMask) - 4; if(nIndexLastNoMask < 2) return false; TCHAR *pLastNoMask = lpszMask + nIndexLastNoMask; if(*pLastNoMask == _T('\\')) *pLastNoMask = 0; TCHAR *p = lpszMask; TCHAR *s = 0; while(*(++p) != 0) { if(*p == _T('\\')) s = p; } if(s != 0) *s = 0; lstrcat(lpszMask, _T("\\*.*")); return true;}bool JELFileInstaller::MakeChildMask(LPTSTR lpszMask, LPCTSTR lpszChildDir){ if(lpszMask == 0 || lpszChildDir == 0) return false; int nIndexLastSlash = lstrlen(lpszMask) - 3; if(nIndexLastSlash < 3) return false; *(lpszMask + nIndexLastSlash) = 0; lstrcat(lpszMask, lpszChildDir); lstrcat(lpszMask, _T("\\*.*")); return true;}HRESULT JELFileInstaller::SendMessage(LPVOID p){ p; return E_NOTIMPL;}/* Implementation of JELShortcutInstaller */JELShortcutInstaller::JELShortcutInstaller(const InstallData *ptrData, Installer *ptrOwner) : pData(ptrData), pOwner(ptrOwner) {}JELShortcutInstaller::~JELShortcutInstaller() {}HRESULT JELShortcutInstaller::Install(){ InstallerLog::Log("Installing shortcuts. . .\n"); // Always install shortcuts for the primary version int nIndex = pData->nIndexNewPrimaryVer; CString strPrimaryDir = (nIndex != -1) ? pData->arPathNames[nIndex] : pData->strInstallDir; // Place shortcuts on the "Start" menu and desktop CString strFile = strPrimaryDir + "\\unlaunch.exe"; CString strUninstallIconPath = strFile; CString strUninstallDesc((LPCSTR)IDS_SHORTCUT_UNINSTALL); CreateShortcut(strFile, strUninstallDesc, strUninstallIconPath, ProgramsMenu, strUninstallDesc, strPrimaryDir, 0); strFile = strPrimaryDir + "\\jedinit.exe"; CreateShortcut(strFile, "Set jEdit Parameters", strFile, ProgramsMenu, CString((LPCSTR)IDS_SHORTCUT_JEDINIT), strPrimaryDir, 0); strFile = strPrimaryDir + "\\jedit.exe"; CString strJEditDesc((LPCSTR)IDS_SHORTCUT_JEDIT); CreateShortcut(strFile, "jEdit", strFile, ProgramsMenu, strJEditDesc, strPrimaryDir, 0); // for primary version CreateShortcut(strFile, "jEdit", strFile, StartMenu, strJEditDesc, strPrimaryDir, 0); CreateShortcut(strFile, "jEdit", strFile, Desktop, strJEditDesc, strPrimaryDir, 0); return S_OK;}HRESULT JELShortcutInstaller::CreateShortcut(LPCSTR lpszPathObj, LPCSTR lpszLinkName, LPCSTR lpszPathIcon, LinkLocation location, LPCSTR lpszDesc, LPCSTR lpszWorkingDir, LPCSTR lpszParams){ ITEMIDLIST *id; char szLinkPath[MAX_PATH]; ZeroMemory(szLinkPath, sizeof(szLinkPath)); SHGetSpecialFolderLocation(NULL, location, &id); SHGetPathFromIDList(id, szLinkPath); if(location == ProgramsMenu) { char szLinkParent[MAX_PATH]; strcpy(szLinkParent, szLinkPath); strcat(szLinkPath, "\\jEdit"); if(-1 == GetFileAttributes(szLinkPath) && !CreateDirectoryEx(szLinkParent, szLinkPath, 0)) return E_FAIL; } strcat(szLinkPath, "\\"); strcat(szLinkPath, lpszLinkName); strcat(szLinkPath, ".lnk"); InstallerLog::Log("Creating shortcut at %s.\n", szLinkPath); HRESULT hres; IShellLink* psl; // Get a pointer to the IShellLink interface. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Set the path to the shortcut target and add the // description. psl->SetPath(lpszPathObj); psl->SetDescription(lpszDesc); psl->SetIconLocation(lpszPathIcon, 0); psl->SetWorkingDirectory(lpszWorkingDir); if(lpszParams) psl->SetArguments(lpszParams); // Query IShellLink for the IPersistFile interface // for saving the shortcut in persistent storage. hres = psl->QueryInterface(__uuidof(IPersistFile), (void**) &ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; // Ensure that the string is Unicode. MultiByteToWideChar(CP_ACP, 0, szLinkPath, -1, wsz, MAX_PATH); // Save the link by calling IPersistFile::Save. hres = ppf->Save(wsz, TRUE); ppf->Release(); } psl->Release(); } InstallerLog::Log("Shortcut creation %s.\n", (hres == S_OK ? "succeeded" : "failed")); return hres;}HRESULT JELShortcutInstaller::Uninstall(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -