?? jelreginstaller.cpp
字號:
/* * JELRegInstaller.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: JELRegInstaller.cpp,v 1.14 2002/02/19 03:33:44 jgellene Exp $ */#include "stdafx.h"#include <string.h>#include "InstallData.h"#include "StringPtr.h"#include "InstallerLog.h"#include "JELRegInstaller.h"#include <assert.h>#include <stdlib.h> // for itoa in debug/* Implementation of JELRegistryInstaller */JELRegistryInstaller::JELRegistryInstaller(const InstallData *ptrData, Installer *ptrOwner) : pData(ptrData), pOwner(ptrOwner) {}JELRegistryInstaller::~JELRegistryInstaller() {}HRESULT JELRegistryInstaller::Install(){ InstallerLog::Log(Message, "Commencing installation of registry entires. . . .\n"); HRESULT hr; // register proxy/stub DLL CString strPath(pData->strInstallDir); strPath += _T("\\jeservps.dll"); if(FAILED(hr = RegisterDLL(strPath, TRUE))) return hr; // registration of unlaunch for "Add/Remove Programs" applet // other data added by COM server RegisterUninstall(); // register COM server strPath = pData->strInstallDir; strPath += _T("\\jeditsrv.exe"); if(FAILED(hr = RegisterEXE(strPath))) { // TODO: try to restore former setting return hr; } // register the context menu handler strPath = pData->strInstallDir; strPath += pData->bUsingTempFileName ? _T("\\jeshlstb.dl_") : _T("\\jeshlstb.dll"); if(FAILED(hr = RegisterDLL(strPath, TRUE))) return hr; // if we are still using the temporary file name, fix the // registration entry so it will be correct after rebooting if(pData->bUsingTempFileName) { if(FAILED(hr = CorrectTempCtxReg())) { InstallerLog::Log(Debug, "Registration of context menu handler could not be corrected.\n"); return hr; } } RegisterPrimaryVersion(); RegisterCmdLineParameters(); return hr;}HRESULT JELRegistryInstaller::RegisterDLL(LPCTSTR szPath, BOOL bRegister){ if(bRegister) { InstallerLog::Log(Message, "Registering %s. . .\n", szPath); } FARPROC proc = 0; HRESULT hr; LPCTSTR szProc = bRegister ? _T("DllRegisterServer") : _T("DllUnregisterServer"); HMODULE hModule = ::LoadLibrary(szPath); if(hModule == 0) { InstallerLog::Log(Error, "Could not load library in %s\n.", szPath); return E_FAIL; } proc = GetProcAddress(hModule, szProc); if(proc == 0) { InstallerLog::Log(Error, "Could not get address for %s in %s\n.", szProc, szPath); hr = E_FAIL; } else { hr = (proc)(); if(hr != S_OK) { if(bRegister) { InstallerLog::Log(Error, "Registration failed; error code 0x%08x.\n"); } hr = E_FAIL; } else { InstallerLog::Log(Message, "Registration succeeded.\n"); } } if(hModule != 0) FreeLibrary(hModule); return hr;}HRESULT JELRegistryInstaller::RegisterEXE(LPCTSTR szPath, BOOL bRegister){ if(bRegister) { InstallerLog::Log(Message, "Registering %s. . .\n", szPath); } CString strCmdLine(szPath); strCmdLine += (bRegister ? _T(" /RegServer") : _T(" /UnregServer")); CStringBuf<> bufCmdLine(strCmdLine); STARTUPINFO si; ::ZeroMemory(&si, sizeof(si)); PROCESS_INFORMATION pi; BOOL bReturn = CreateProcess(0, bufCmdLine, 0, 0, 0, 0, 0, 0, &si, &pi); if(!bReturn) { if(bRegister) InstallerLog::Log(Error, "Registration failed.\n"); DWORD swError = GetLastError(); } else { if(bRegister) InstallerLog::Log(Message, "Registration succeeded.\n"); } return bReturn ? S_OK : E_FAIL;}HRESULT JELRegistryInstaller::CorrectTempCtxReg(){ HKEY hKey = 0; CString strClassKeyPath((LPCSTR)IDS_REG_CTX_SERVER_KEY); int nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, strClassKeyPath, 0, KEY_SET_VALUE, &hKey); if(nResult == ERROR_SUCCESS) { nResult = RegSetValueEx(hKey, 0, 0, REG_SZ, (const LPBYTE)(LPCTSTR)pData->strInstallFinalPath, InstallData::GetBufferByteLen(pData->strInstallFinalPath)); } RegCloseKey(hKey); return nResult == ERROR_SUCCESS ? S_OK : E_FAIL;}HRESULT JELRegistryInstaller::RegisterUninstall(){ InstallerLog::Log(Message, "Registering uninstall data for Add/Remove programs...\n"); HKEY hKey; CString strUninstallKey((LPCSTR)IDS_REG_UNINSTALL_KEY); strUninstallKey += pData->strInstallVersion; ::OutputDebugString(strUninstallKey); int nResult = RegCreateKeyEx(HKEY_CURRENT_USER, strUninstallKey, 0, 0, REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hKey, 0); if(nResult == ERROR_SUCCESS) { InstallerLog::Log(Debug, "Found uninstall key\n"); CString strUninstall(pData->strInstallDir); strUninstall += "\\unlaunch.exe"; nResult = RegSetValueEx(hKey, "UninstallString", 0, REG_SZ, (const LPBYTE)(LPCTSTR)strUninstall, InstallData::GetBufferByteLen(strUninstall)); InstallerLog::Log(Debug, "UninstallString %s.\n", nResult == ERROR_SUCCESS ? "OK" : "error"); CString strInstall(pData->strInstallDir); strInstall += "\\jedit.exe /i "; strInstall += pData->strJavaHome; nResult = RegSetValueEx(hKey, "InstallPath", 0, REG_SZ, (const LPBYTE)(LPCTSTR)strInstall, InstallData::GetBufferByteLen(strInstall)); InstallerLog::Log(Debug, "Install Path %s.\n", nResult == ERROR_SUCCESS ? "OK" : "error"); CString strDisplayIcon(pData->strInstallDir); strDisplayIcon += "\\jedit.exe, 0"; nResult = RegSetValueEx(hKey, "DisplayIcon", 0, REG_SZ, (const LPBYTE)(LPCTSTR)strDisplayIcon, InstallData::GetBufferByteLen(strDisplayIcon)); InstallerLog::Log(Debug, "Display Icon %s.\n", nResult == ERROR_SUCCESS ? "OK" : "error"); } else InstallerLog::Log(Error, "Could not find uninstall registry key.\n"); RegCloseKey(hKey); InstallerLog::Log(Message, "Uninstall registration %s.\n", nResult == ERROR_SUCCESS ? "succeeded" : "failed"); return (nResult == ERROR_SUCCESS ? S_OK : E_FAIL);}HRESULT JELRegistryInstaller::RegisterPrimaryVersion(){ // register scripting object and designated context menu handler // get default value for GUID // get ProgID under GUID // default value becomes default value for class 'JEdit.JEditLauncher' // CLSID is GUID // CurVer is ProgID CString strClassKey(_T("CLSID\\")); const CString& strGUID = pData->strInstallGUID; strClassKey += strGUID; CString strClassName; CString strCurVer; CString strCurVerDir; HKEY hKey; int nResult; int nCounter = 20; // waiting for possible registration of new server in separate thread do { Sleep(50); nResult = RegOpenKeyEx(HKEY_CLASSES_ROOT, strClassKey, 0, KEY_READ | KEY_QUERY_VALUE, &hKey); } while(nResult != ERROR_SUCCESS && --nCounter != 0); if(nResult == ERROR_SUCCESS) { CStringBuf<>pClassBuf(strClassName); DWORD dwLength = pClassBuf.Size(); RegQueryValueEx(hKey, 0, 0, 0, (LPBYTE)pClassBuf, &dwLength); HKEY hSubkey; nResult = RegOpenKeyEx(hKey, _T("ProgID"), 0, KEY_READ, &hSubkey); if(nResult == ERROR_SUCCESS) { CStringBuf<>pCurVerBuf(strCurVer); dwLength = pCurVerBuf.Size(); RegQueryValueEx(hSubkey, 0, 0, 0, (LPBYTE)pCurVerBuf, &dwLength); } RegCloseKey(hSubkey); nResult = RegOpenKeyEx(hKey, _T("LocalServer32"), 0, KEY_READ, &hSubkey); if(nResult == ERROR_SUCCESS) { CStringBuf<>pCurVerDirBuf(strCurVerDir); dwLength = pCurVerDirBuf.Size(); RegQueryValueEx(hSubkey, 0, 0, 0, (LPBYTE)pCurVerDirBuf, &dwLength); InstallData::ShortenToDirectory(pCurVerDirBuf); } RegCloseKey(hSubkey); } RegCloseKey(hKey); nResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("JEdit.JEditLauncher"), 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0); if(nResult == ERROR_SUCCESS) { RegSetValueEx(hKey, 0, 0, REG_SZ, (LPBYTE)(LPCTSTR)strClassName, InstallData::GetBufferByteLen(strClassName)); HKEY hSubkey; nResult = RegCreateKeyEx(hKey, _T("CLSID"), 0, 0, 0, KEY_ALL_ACCESS, 0, &hSubkey, 0); if(nResult == ERROR_SUCCESS) { RegSetValueEx(hSubkey, 0, 0, REG_SZ, (LPBYTE)(LPCTSTR)strGUID, InstallData::GetBufferByteLen(strGUID)); } RegCloseKey(hSubkey); nResult = RegCreateKeyEx(hKey, _T("CurVer"), 0, 0, 0, KEY_ALL_ACCESS, 0, &hSubkey, 0); if(nResult == ERROR_SUCCESS) { RegSetValueEx(hSubkey, 0, 0, REG_SZ, (LPBYTE)(LPCTSTR)strCurVer, InstallData::GetBufferByteLen(strCurVer)); } RegCloseKey(hSubkey); } RegCloseKey(hKey); // unregister uninstall information for jEdit 3.2 int nResultDel = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"), 0, KEY_WRITE, &hKey); if(nResultDel == ERROR_SUCCESS) RegDeleteKey(hKey, _T("jEdit 3.2")); RegCloseKey(hKey); if(nResult != ERROR_SUCCESS) return E_FAIL; return S_OK;}HRESULT JELRegistryInstaller::RegisterCmdLineParameters(){ bool bResult = true; InstallerLog::Log(Message, "Registering command line parameters. . . .\n"); HKEY hLauncherKey, hVersionKey; DWORD dwDisp; int nResult; DWORD dwValueSize; TCHAR szBuf[MAX_PATH]; TCHAR* arszValues[] = { _T("Java Executable"), _T("Java Options"), _T("jEdit Target"), _T("jEdit Options"), _T("jEdit Working Directory"), _T("Launcher GUID"), _T("Installation Directory"), _T("Launcher Log Level") }; ZeroMemory(szBuf, MAX_PATH);/* enum { JavaExec, JavaOptions, jEditTarget, jEditOptions, Server, WorkingDir, GUID, InstallDir };*/ // ask if parameters should be retained from last installation bool bUseOldParameters = false; if((pData->bIs32 || pData->bIs40) && IDYES == MessageBox(0, "Do you wish to retain command line parameters from your existing installation of jEditLauncher?", "jEditLauncher", MB_ICONQUESTION | MB_YESNO)) { InstallerLog::Log(Message, "Using parameters from existing installation.\n"); bUseOldParameters = true; } else { InstallerLog::Log(Message, "Writing default parameters.\n"); } CString strLauncherParamKeyPath((LPCSTR)IDS_REG_LAUNCHER_PARAM_KEY); RegCreateKeyEx(HKEY_CURRENT_USER, strLauncherParamKeyPath, 0, 0, 0, KEY_ALL_ACCESS, 0, &hLauncherKey, 0); CString strVersion(pData->strInstallVersion); RegCreateKeyEx(hLauncherKey, strVersion, 0, 0, 0, KEY_ALL_ACCESS, 0, &hVersionKey, &dwDisp); // rewrite key from 3.2 to 4.0 if(bUseOldParameters && pData->bIs32 && !pData->bIs40) { HKEY hKey32; int nResult32 = RegOpenKeyEx(hLauncherKey, "3.2", 0, KEY_READ, &hKey32); if(nResult32 == ERROR_SUCCESS) { nResult32 = RegCopyKey(hKey32, hLauncherKey, "4.0"); RegCloseKey(hKey32); if(nResult32 == ERROR_SUCCESS) { InstallerLog::Log(Debug, "Copied key information from version 3.2 to 4.0.\n"); nResult32 = RegDeleteKey(hLauncherKey, _T("3.2")); InstallerLog::Log(Debug, "version 3.2 parameters %s\n", nResult32 == ERROR_SUCCESS ? "deleted" : "not deleted"); } else { bUseOldParameters = false; InstallerLog::Log(Error, "Could not copy parameters from version 3.2 to 4.0, new parameters must be supplied.\n"); } } else { RegCloseKey(hKey32); bUseOldParameters = false; InstallerLog::Log(Error, "Could not find parameters from version 3.2 to copy, new parameters must be supplied.\n"); } } // "Java Executable" - set if old parameter or if not available; // do not update if user elects to retain old parameters dwValueSize = MAX_PATH; nResult = RegQueryValueEx(hVersionKey, arszValues[0], 0, 0, (LPBYTE)szBuf, &dwValueSize); if(!bUseOldParameters || nResult != ERROR_SUCCESS || dwValueSize == 0) { CString strJavaExec(pData->strJavaHome); strJavaExec += _T("\\javaw.exe"); nResult = RegSetValueEx(hVersionKey, arszValues[0], 0, REG_SZ, (LPBYTE)(LPCTSTR)strJavaExec, InstallData::GetBufferByteLen(strJavaExec)); if(ERROR_SUCCESS == nResult) { InstallerLog::Log(Debug, "Writing \"Java Executable\" registry parameter: %s\n", (LPCSTR)strJavaExec); } else { InstallerLog::Log(Error, "Could not write \"Java Executable\" registry parameter.\n"); bResult &= false; } } // "Java Options" - set if new parameters of if unavailable; // update regardless whenther user elects to retain old parameters dwValueSize = MAX_PATH; nResult = RegQueryValueEx(hVersionKey, arszValues[1], 0, 0, (LPBYTE)szBuf, &dwValueSize); if(!bUseOldParameters || nResult != ERROR_SUCCESS || dwValueSize == 0) { bUseOldParameters = false; CString strJavaOptions(_T("-mx32m -jar"));// strJavaOptions.Format(IDS_REG_JAVAPARAM_DEFAULT,// pData->arPathNames[pData->nIndexSubjectVer]); nResult = RegSetValueEx(hVersionKey, arszValues[1], 0, REG_SZ, (LPBYTE)(LPCTSTR)strJavaOptions, InstallData::GetBufferByteLen(strJavaOptions)); if(ERROR_SUCCESS == nResult) { InstallerLog::Log(Debug, "Writing \"Java Options\" registry parameter: %s\n", (LPCSTR)strJavaOptions); } else { InstallerLog::Log(Error,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -