void System::LaunchExplorer( ) { wstring buf( MAX_PATH, '\0' ); GetWindowsDirectory( &buf[ 0 ], MAX_PATH ); buf.resize( wcslen( &buf[ 0 ] ) ); buf += L"\\explorer.exe"; STARTUPINFO cif; ZeroMemory( &cif, sizeof( cif ) ); if( !IsExplorerRunning( ) ) { if( CreateProcess( buf.c_str( ), 0, 0, 0, FALSE, 0, 0, 0, &cif, &m_pInfo ) ) { m_bBootExplorer = true; } else { MessageBox( 0, L"Explorer was not launched", L"ERROR: Unknown Error", MB_ICONERROR | MB_OK ); } } }
int SetupHelperApp::OnRun() { #ifdef _WIN64 DBG("--- x64 SetupHelper"); #else DBG("--- x86 SetupHelper"); #endif if (__argc < 3) return -1; std::vector<ProcessInfo> processes; DBG("Get processes (1)"); if (!GetProcesses(processes)) return -1; DBG("Got processes (1):"); for (size_t i = 0; i < processes.size(); ++i) { DBG(i << ": " << processes[i].pid); } // Kill all Explorer and cvslock processes for (size_t i = 0; i < processes.size(); ++i) { if (!_tcsicmp(processes[i].image.c_str(), wxT("explorer.exe"))) { DBG("Killing Explorer"); // Show dialog wxProgressDialog* dlg = new wxProgressDialog(wxT("TortoiseCVS Setup"), wxText(__argv[1])); dlg->Show(); // Kill Explorer TerminateProcess(processes[i]); int i = 0; while (IsProcessRunning(processes[i].pid) && (i < 50)) { dlg->Update((i+1)*100/50); Sleep(50); } // Avoid the Active Desktop error message HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer", 0, KEY_WRITE, &hKey)) { DWORD data = 0; RegSetValueExA(hKey, "FaultKey", 0, REG_DWORD, reinterpret_cast<BYTE*>(&data), sizeof(DWORD)); } dlg->Destroy(); } else if (!_tcsicmp(processes[i].image.c_str(), wxT("cvslock.exe"))) { // Kill CVSNT lock service TerminateProcess(processes[i]); } } // Show dialog wxProgressDialog* dlg = new wxProgressDialog(wxT("TortoiseCVS Setup"), wxText(__argv[1])); dlg->Show(); // Wait for Explorer restart for (int i = 0; i < 50; ++i) { if (IsExplorerRunning()) break; dlg->Update((i+1)*100/50); Sleep(50); } if (!IsExplorerRunning()) { dlg->Update(0); STARTUPINFOA startupinfo; startupinfo.cb = sizeof(STARTUPINFOA); startupinfo.lpReserved = 0; startupinfo.lpDesktop = 0; startupinfo.lpTitle = 0; startupinfo.dwFlags = 0; startupinfo.cbReserved2 = 0; startupinfo.lpReserved2 = 0; PROCESS_INFORMATION processinfo; CreateProcessA(0, "explorer.exe", 0, 0, FALSE, 0, 0, 0, &startupinfo, &processinfo); CloseHandle(processinfo.hProcess); CloseHandle(processinfo.hThread); for (int i = 0; i < 10; ++i) { Sleep(50); dlg->Update((i+1)*100/10); } } dlg->Destroy(); DBG("Check remaining processes"); bool anyLeft = true; while (anyLeft) { processes.clear(); DBG("Get processes (2)"); if (!GetProcesses(processes)) return -1; DBG("Got processes (2):"); for (size_t i = 0; i < processes.size(); ++i) { DBG(i << ": " << processes[i].pid); } anyLeft = false; for (size_t i = 0; i < processes.size(); ++i) { if (_tcsicmp(processes[i].image.c_str(), wxT("explorer.exe"))) { anyLeft = true; // Ask user to close application wxString msg; msg << wxT("The application "); if (processes[i].title.empty()) { // No title found (may be minimized to tray etc.) msg << processes[i].image; } else msg << wxT("'") << processes[i].title << wxT("' (") << processes[i].image << wxT(")"); msg << wxT("\nneeds to be closed before TortoiseCVS setup can continue.\n") << wxT("Please close the application and click OK, or click Cancel to leave the process ") << wxT("running.\nIn the latter case, you will be required to reboot Windows after installation."); if (MessageBox(0, msg.c_str(), wxT("TortoiseCVS Setup"), MB_OKCANCEL | MB_ICONINFORMATION) == IDCANCEL) return 1; } } } DBG("Loop done"); if (__argv[2][0] == 'b') return 0; // Delete any renamed DLL's // TODO: Make this work even when installing to a different directory std::string rootDir(GetRootDir()); std::string src(rootDir); src += "TortoiseShell.dll_renamed"; DBG("Deleting " << src); DeleteFileA(src.c_str()); src = rootDir; src += "TortoiseShell64.dll_renamed"; DBG("Deleting " << src); DeleteFileA(src.c_str()); src = rootDir; src += "TortoiseAct.exe_renamed"; DBG("Deleting " << src); DeleteFileA(src.c_str()); DBG("Exit: 0"); return 0; }