[email protected] | 9e790bd | 2011-01-10 23:48:54 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | e6b5bc2 | 2011-09-08 22:01:56 | [diff] [blame] | 5 | #include "chrome/browser/chrome_browser_main_win.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 6 | |
[email protected] | 71b73f0 | 2011-04-06 15:57:29 | [diff] [blame] | 7 | #include <windows.h> |
[email protected] | e078590 | 2011-05-19 23:34:17 | [diff] [blame] | 8 | #include <shellapi.h> |
[email protected] | 4a0765a | 2009-05-08 23:12:25 | [diff] [blame] | 9 | |
[email protected] | c83dd91 | 2010-04-06 18:50:51 | [diff] [blame] | 10 | #include <algorithm> |
| 11 | |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 12 | #include "base/command_line.h" |
[email protected] | ae0f077 | 2010-08-13 04:54:10 | [diff] [blame] | 13 | #include "base/environment.h" |
[email protected] | 7cf1b6ce | 2010-03-20 06:37:01 | [diff] [blame] | 14 | #include "base/i18n/rtl.h" |
[email protected] | 3b63f8f4 | 2011-03-28 01:54:15 | [diff] [blame] | 15 | #include "base/memory/scoped_ptr.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 16 | #include "base/path_service.h" |
[email protected] | e078590 | 2011-05-19 23:34:17 | [diff] [blame] | 17 | #include "base/scoped_native_library.h" |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 18 | #include "base/string_number_conversions.h" |
[email protected] | be1ce6a7 | 2010-08-03 14:35:22 | [diff] [blame] | 19 | #include "base/utf_string_conversions.h" |
[email protected] | 935aa54 | 2010-10-15 01:59:15 | [diff] [blame] | 20 | #include "base/win/windows_version.h" |
[email protected] | ecb924c | 2011-03-17 00:34:09 | [diff] [blame] | 21 | #include "base/win/wrapped_window_proc.h" |
[email protected] | a3abd557 | 2011-04-15 02:09:33 | [diff] [blame] | 22 | #include "chrome/browser/browser_util_win.h" |
[email protected] | 82073579 | 2010-07-29 23:40:01 | [diff] [blame] | 23 | #include "chrome/browser/first_run/first_run.h" |
[email protected] | cd1adc2 | 2009-01-16 01:29:22 | [diff] [blame] | 24 | #include "chrome/browser/metrics/metrics_service.h" |
[email protected] | f8b2ca3 | 2011-11-22 14:58:23 | [diff] [blame^] | 25 | #include "chrome/browser/profiles/profile_info_cache.h" |
| 26 | #include "chrome/browser/profiles/profile_shortcut_manager_win.h" |
[email protected] | 71b73f0 | 2011-04-06 15:57:29 | [diff] [blame] | 27 | #include "chrome/browser/ui/browser_list.h" |
[email protected] | 9e790bd | 2011-01-10 23:48:54 | [diff] [blame] | 28 | #include "chrome/browser/ui/views/uninstall_view.h" |
[email protected] | ecb924c | 2011-03-17 00:34:09 | [diff] [blame] | 29 | #include "chrome/common/chrome_constants.h" |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 30 | #include "chrome/common/chrome_result_codes.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 31 | #include "chrome/common/chrome_switches.h" |
| 32 | #include "chrome/common/env_vars.h" |
[email protected] | bf6117c7e | 2010-12-01 06:00:25 | [diff] [blame] | 33 | #include "chrome/installer/util/browser_distribution.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 34 | #include "chrome/installer/util/helper.h" |
| 35 | #include "chrome/installer/util/install_util.h" |
| 36 | #include "chrome/installer/util/shell_util.h" |
[email protected] | 4573fbd | 2011-10-31 20:25:18 | [diff] [blame] | 37 | #include "content/public/common/main_function_params.h" |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 38 | #include "grit/app_locale_settings.h" |
[email protected] | 34ac8f3 | 2009-02-22 23:03:27 | [diff] [blame] | 39 | #include "grit/chromium_strings.h" |
| 40 | #include "grit/generated_resources.h" |
[email protected] | c051a1b | 2011-01-21 23:30:17 | [diff] [blame] | 41 | #include "ui/base/l10n/l10n_util.h" |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 42 | #include "ui/base/l10n/l10n_util_win.h" |
[email protected] | 75b6805 | 2011-02-03 06:01:16 | [diff] [blame] | 43 | #include "ui/base/message_box_win.h" |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 44 | #include "ui/gfx/platform_font_win.h" |
[email protected] | 477ae05 | 2011-11-18 23:53:57 | [diff] [blame] | 45 | #include "ui/views/focus/accelerator_handler.h" |
[email protected] | c13be0d | 2011-11-22 02:09:58 | [diff] [blame] | 46 | #include "ui/views/widget/widget.h" |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 47 | |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 48 | namespace { |
[email protected] | ecb924c | 2011-03-17 00:34:09 | [diff] [blame] | 49 | |
[email protected] | a08ba82 | 2011-02-20 07:45:47 | [diff] [blame] | 50 | typedef HRESULT (STDAPICALLTYPE* RegisterApplicationRestartProc)( |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 51 | const wchar_t* command_line, |
| 52 | DWORD flags); |
[email protected] | ecb924c | 2011-03-17 00:34:09 | [diff] [blame] | 53 | |
| 54 | void InitializeWindowProcExceptions() { |
| 55 | // Get the breakpad pointer from chrome.exe |
| 56 | base::win::WinProcExceptionFilter exception_filter = |
| 57 | reinterpret_cast<base::win::WinProcExceptionFilter>( |
| 58 | ::GetProcAddress(::GetModuleHandle( |
| 59 | chrome::kBrowserProcessExecutableName), |
| 60 | "CrashForException")); |
| 61 | exception_filter = base::win::SetWinProcExceptionFilter(exception_filter); |
| 62 | DCHECK(!exception_filter); |
| 63 | } |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 64 | |
| 65 | // gfx::Font callbacks |
| 66 | void AdjustUIFont(LOGFONT* logfont) { |
| 67 | l10n_util::AdjustUIFont(logfont); |
| 68 | } |
| 69 | |
| 70 | int GetMinimumFontSize() { |
| 71 | int min_font_size; |
| 72 | base::StringToInt(l10n_util::GetStringUTF16(IDS_MINIMUM_UI_FONT_SIZE), |
| 73 | &min_font_size); |
| 74 | return min_font_size; |
| 75 | } |
| 76 | |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 77 | } // namespace |
| 78 | |
[email protected] | 1152b7e | 2009-09-14 03:26:03 | [diff] [blame] | 79 | void RecordBreakpadStatusUMA(MetricsService* metrics) { |
[email protected] | c83dd91 | 2010-04-06 18:50:51 | [diff] [blame] | 80 | DWORD len = ::GetEnvironmentVariableW( |
| 81 | ASCIIToWide(env_vars::kNoOOBreakpad).c_str() , NULL, 0); |
[email protected] | 1152b7e | 2009-09-14 03:26:03 | [diff] [blame] | 82 | metrics->RecordBreakpadRegistration((len == 0)); |
| 83 | metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent()); |
| 84 | } |
| 85 | |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 86 | void WarnAboutMinimumSystemRequirements() { |
[email protected] | 935aa54 | 2010-10-15 01:59:15 | [diff] [blame] | 87 | if (base::win::GetVersion() < base::win::VERSION_XP) { |
[email protected] | 34f73fb | 2010-03-24 20:50:34 | [diff] [blame] | 88 | // Display a warning message if the user is running chrome on Windows 2000. |
[email protected] | 0f26d7b | 2011-01-05 19:10:44 | [diff] [blame] | 89 | const string16 text = |
| 90 | l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP); |
| 91 | const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
[email protected] | 75b6805 | 2011-02-03 06:01:16 | [diff] [blame] | 92 | ui::MessageBox(NULL, text, caption, MB_OK | MB_ICONWARNING | MB_TOPMOST); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 93 | } |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 94 | } |
| 95 | |
[email protected] | 45d7276 | 2011-04-15 18:58:20 | [diff] [blame] | 96 | void RecordBrowserStartupTime() { |
| 97 | // Calculate the time that has elapsed from our own process creation. |
| 98 | FILETIME creation_time = {}; |
| 99 | FILETIME ignore = {}; |
| 100 | ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore, |
| 101 | &ignore); |
| 102 | |
[email protected] | 28f576f | 2011-08-26 20:46:55 | [diff] [blame] | 103 | RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime", |
| 104 | base::Time::Now() - base::Time::FromFileTime(creation_time)); |
[email protected] | 45d7276 | 2011-04-15 18:58:20 | [diff] [blame] | 105 | } |
| 106 | |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 107 | int AskForUninstallConfirmation() { |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 108 | int ret = content::RESULT_CODE_NORMAL_EXIT; |
[email protected] | 956b3d3 | 2011-09-28 09:38:48 | [diff] [blame] | 109 | views::Widget::CreateWindow(new UninstallView(&ret))->Show(); |
[email protected] | 047f622 | 2009-07-29 23:34:56 | [diff] [blame] | 110 | views::AcceleratorHandler accelerator_handler; |
[email protected] | 4d628531 | 2011-10-24 07:19:51 | [diff] [blame] | 111 | MessageLoopForUI::current()->RunWithDispatcher(&accelerator_handler); |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 112 | return ret; |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 113 | } |
| 114 | |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 115 | void ShowCloseBrowserFirstMessageBox() { |
[email protected] | 0f26d7b | 2011-01-05 19:10:44 | [diff] [blame] | 116 | const string16 text = l10n_util::GetStringUTF16(IDS_UNINSTALL_CLOSE_APP); |
| 117 | const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 118 | const UINT flags = MB_OK | MB_ICONWARNING | MB_TOPMOST; |
[email protected] | 75b6805 | 2011-02-03 06:01:16 | [diff] [blame] | 119 | ui::MessageBox(NULL, text, caption, flags); |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | int DoUninstallTasks(bool chrome_still_running) { |
[email protected] | a173cc9 | 2009-08-20 23:26:37 | [diff] [blame] | 123 | // We want to show a warning to user (and exit) if Chrome is already running |
| 124 | // *before* we show the uninstall confirmation dialog box. But while the |
| 125 | // uninstall confirmation dialog is up, user might start Chrome, so we |
| 126 | // check once again after user acknowledges Uninstall dialog. |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 127 | if (chrome_still_running) { |
| 128 | ShowCloseBrowserFirstMessageBox(); |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 129 | return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE; |
[email protected] | 53c38d23 | 2009-02-13 20:52:18 | [diff] [blame] | 130 | } |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 131 | int ret = AskForUninstallConfirmation(); |
[email protected] | a3abd557 | 2011-04-15 02:09:33 | [diff] [blame] | 132 | if (browser_util::IsBrowserAlreadyRunning()) { |
[email protected] | a173cc9 | 2009-08-20 23:26:37 | [diff] [blame] | 133 | ShowCloseBrowserFirstMessageBox(); |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 134 | return chrome::RESULT_CODE_UNINSTALL_CHROME_ALIVE; |
[email protected] | a173cc9 | 2009-08-20 23:26:37 | [diff] [blame] | 135 | } |
| 136 | |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 137 | if (ret != chrome::RESULT_CODE_UNINSTALL_USER_CANCEL) { |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 138 | // The following actions are just best effort. |
[email protected] | 8e96e50 | 2010-10-21 20:57:12 | [diff] [blame] | 139 | VLOG(1) << "Executing uninstall actions"; |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 140 | if (!FirstRun::RemoveSentinel()) |
[email protected] | 8e96e50 | 2010-10-21 20:57:12 | [diff] [blame] | 141 | VLOG(1) << "Failed to delete sentinel file."; |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 142 | // We want to remove user level shortcuts and we only care about the ones |
| 143 | // created by us and not by the installer so |alternate| is false. |
[email protected] | bf6117c7e | 2010-12-01 06:00:25 | [diff] [blame] | 144 | BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
| 145 | if (!ShellUtil::RemoveChromeDesktopShortcut(dist, ShellUtil::CURRENT_USER, |
[email protected] | f8b2ca3 | 2011-11-22 14:58:23 | [diff] [blame^] | 146 | false)) { |
[email protected] | 8e96e50 | 2010-10-21 20:57:12 | [diff] [blame] | 147 | VLOG(1) << "Failed to delete desktop shortcut."; |
[email protected] | f8b2ca3 | 2011-11-22 14:58:23 | [diff] [blame^] | 148 | } |
| 149 | if (!ShellUtil::RemoveChromeDesktopShortcutsWithAppendedNames( |
| 150 | ProfileShortcutManagerWin::GenerateShortcutsFromProfiles( |
| 151 | ProfileInfoCache::GetProfileNames()))) { |
| 152 | VLOG(1) << "Failed to delete desktop profiles shortcuts."; |
| 153 | } |
[email protected] | bf6117c7e | 2010-12-01 06:00:25 | [diff] [blame] | 154 | if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist, |
[email protected] | f8b2ca3 | 2011-11-22 14:58:23 | [diff] [blame^] | 155 | ShellUtil::CURRENT_USER)) { |
[email protected] | 8e96e50 | 2010-10-21 20:57:12 | [diff] [blame] | 156 | VLOG(1) << "Failed to delete quick launch shortcut."; |
[email protected] | f8b2ca3 | 2011-11-22 14:58:23 | [diff] [blame^] | 157 | } |
[email protected] | 4df8786f | 2009-04-17 13:24:57 | [diff] [blame] | 158 | } |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 159 | return ret; |
| 160 | } |
| 161 | |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 162 | // ChromeBrowserMainPartsWin --------------------------------------------------- |
| 163 | |
| 164 | ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin( |
[email protected] | 4573fbd | 2011-10-31 20:25:18 | [diff] [blame] | 165 | const content::MainFunctionParams& parameters) |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 166 | : ChromeBrowserMainParts(parameters) { |
| 167 | } |
| 168 | |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 169 | void ChromeBrowserMainPartsWin::ToolkitInitialized() { |
| 170 | ChromeBrowserMainParts::ToolkitInitialized(); |
| 171 | gfx::PlatformFontWin::adjust_font_callback = &AdjustUIFont; |
| 172 | gfx::PlatformFontWin::get_minimum_font_size_callback = &GetMinimumFontSize; |
| 173 | } |
| 174 | |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 175 | void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() { |
[email protected] | c748094 | 2011-11-08 19:18:27 | [diff] [blame] | 176 | ChromeBrowserMainParts::PreMainMessageLoopStart(); |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 177 | if (!parameters().ui_task) { |
| 178 | // Make sure that we know how to handle exceptions from the message loop. |
| 179 | InitializeWindowProcExceptions(); |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // static |
| 184 | void ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment( |
| 185 | const CommandLine& parsed_command_line) { |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 186 | // Clear this var so child processes don't show the dialog by default. |
[email protected] | ae0f077 | 2010-08-13 04:54:10 | [diff] [blame] | 187 | scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 188 | env->UnSetVar(env_vars::kShowRestart); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 189 | |
| 190 | // For non-interactive tests we don't restart on crash. |
[email protected] | ae0f077 | 2010-08-13 04:54:10 | [diff] [blame] | 191 | if (env->HasVar(env_vars::kHeadless)) |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 192 | return; |
| 193 | |
| 194 | // If the known command-line test options are used we don't create the |
| 195 | // environment block which means we don't get the restart dialog. |
| 196 | if (parsed_command_line.HasSwitch(switches::kBrowserCrashTest) || |
| 197 | parsed_command_line.HasSwitch(switches::kBrowserAssertTest) || |
| 198 | parsed_command_line.HasSwitch(switches::kNoErrorDialogs)) |
| 199 | return; |
| 200 | |
| 201 | // The encoding we use for the info is "title|context|direction" where |
| 202 | // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending |
| 203 | // on the current locale. |
[email protected] | 6baca1a | 2010-08-14 00:17:05 | [diff] [blame] | 204 | string16 dlg_strings(l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_TITLE)); |
| 205 | dlg_strings.push_back('|'); |
[email protected] | 1c53ffde1 | 2010-08-17 22:40:31 | [diff] [blame] | 206 | string16 adjusted_string( |
| 207 | l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_CONTENT)); |
[email protected] | c32d31e | 2010-11-24 07:27:42 | [diff] [blame] | 208 | base::i18n::AdjustStringForLocaleDirection(&adjusted_string); |
[email protected] | 6baca1a | 2010-08-14 00:17:05 | [diff] [blame] | 209 | dlg_strings.append(adjusted_string); |
| 210 | dlg_strings.push_back('|'); |
| 211 | dlg_strings.append(ASCIIToUTF16( |
| 212 | base::i18n::IsRTL() ? env_vars::kRtlLocale : env_vars::kLtrLocale)); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 213 | |
[email protected] | 6baca1a | 2010-08-14 00:17:05 | [diff] [blame] | 214 | env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings)); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 215 | } |
| 216 | |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 217 | // static |
| 218 | void ChromeBrowserMainPartsWin::RegisterApplicationRestart( |
| 219 | const CommandLine& parsed_command_line) { |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 220 | DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA); |
| 221 | base::ScopedNativeLibrary library(FilePath(L"kernel32.dll")); |
| 222 | // Get the function pointer for RegisterApplicationRestart. |
[email protected] | a08ba82 | 2011-02-20 07:45:47 | [diff] [blame] | 223 | RegisterApplicationRestartProc register_application_restart = |
| 224 | static_cast<RegisterApplicationRestartProc>( |
| 225 | library.GetFunctionPointer("RegisterApplicationRestart")); |
[email protected] | 7b67275 | 2011-07-07 06:39:15 | [diff] [blame] | 226 | if (!register_application_restart) { |
| 227 | LOG(WARNING) << "Cannot find RegisterApplicationRestart in kernel32.dll"; |
| 228 | return; |
| 229 | } |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 230 | // The Windows Restart Manager expects a string of command line flags only, |
| 231 | // without the program. |
| 232 | CommandLine command_line(CommandLine::NO_PROGRAM); |
[email protected] | a40ca430 | 2011-05-14 01:10:24 | [diff] [blame] | 233 | command_line.AppendArguments(parsed_command_line, false); |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 234 | if (!command_line.HasSwitch(switches::kRestoreLastSession)) |
| 235 | command_line.AppendSwitch(switches::kRestoreLastSession); |
[email protected] | 61a4c6f | 2011-07-20 04:54:52 | [diff] [blame] | 236 | if (command_line.GetCommandLineString().length() > RESTART_MAX_CMD_LINE) { |
[email protected] | 7b67275 | 2011-07-07 06:39:15 | [diff] [blame] | 237 | LOG(WARNING) << "Command line too long for RegisterApplicationRestart"; |
| 238 | return; |
| 239 | } |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 240 | |
| 241 | // Restart Chrome if the computer is restarted as the result of an update. |
| 242 | // This could be extended to handle crashes, hangs, and patches. |
[email protected] | 9dc12406b | 2011-03-03 15:50:30 | [diff] [blame] | 243 | HRESULT hr = register_application_restart( |
[email protected] | 61a4c6f | 2011-07-20 04:54:52 | [diff] [blame] | 244 | command_line.GetCommandLineString().c_str(), |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 245 | RESTART_NO_CRASH | RESTART_NO_HANG | RESTART_NO_PATCH); |
| 246 | DCHECK(SUCCEEDED(hr)) << "RegisterApplicationRestart failed."; |
[email protected] | 0fd23af | 2011-02-20 06:33:04 | [diff] [blame] | 247 | } |
| 248 | |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 249 | void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() { |
| 250 | ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage), |
| 251 | ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle), |
| 252 | MB_OK | MB_ICONERROR | MB_TOPMOST); |
| 253 | } |
| 254 | |
| 255 | // static |
| 256 | int ChromeBrowserMainPartsWin::HandleIconsCommands( |
| 257 | const CommandLine& parsed_command_line) { |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 258 | if (parsed_command_line.HasSwitch(switches::kHideIcons)) { |
[email protected] | 0f26d7b | 2011-01-05 19:10:44 | [diff] [blame] | 259 | string16 cp_applet; |
[email protected] | 935aa54 | 2010-10-15 01:59:15 | [diff] [blame] | 260 | base::win::Version version = base::win::GetVersion(); |
| 261 | if (version >= base::win::VERSION_VISTA) { |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 262 | cp_applet.assign(L"Programs and Features"); // Windows Vista and later. |
[email protected] | 935aa54 | 2010-10-15 01:59:15 | [diff] [blame] | 263 | } else if (version >= base::win::VERSION_XP) { |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 264 | cp_applet.assign(L"Add/Remove Programs"); // Windows XP. |
| 265 | } else { |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 266 | return chrome::RESULT_CODE_UNSUPPORTED_PARAM; // Not supported |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 267 | } |
| 268 | |
[email protected] | 0f26d7b | 2011-01-05 19:10:44 | [diff] [blame] | 269 | const string16 msg = |
| 270 | l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet); |
| 271 | const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 272 | const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST; |
[email protected] | 75b6805 | 2011-02-03 06:01:16 | [diff] [blame] | 273 | if (IDOK == ui::MessageBox(NULL, msg, caption, flags)) |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 274 | ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL); |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 275 | |
| 276 | // Exit as we are not launching the browser. |
| 277 | return content::RESULT_CODE_NORMAL_EXIT; |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 278 | } |
| 279 | // We don't hide icons so we shouldn't do anything special to show them |
[email protected] | 1fcfb20 | 2011-07-19 19:53:14 | [diff] [blame] | 280 | return chrome::RESULT_CODE_UNSUPPORTED_PARAM; |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 281 | } |
| 282 | |
[email protected] | b48c918 | 2011-10-26 18:03:30 | [diff] [blame] | 283 | // static |
| 284 | bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() { |
[email protected] | bf6117c7e | 2010-12-01 06:00:25 | [diff] [blame] | 285 | // TODO(tommi): Check if using the default distribution is always the right |
| 286 | // thing to do. |
| 287 | BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
[email protected] | 1db1b49 | 2010-12-16 19:03:37 | [diff] [blame] | 288 | scoped_ptr<Version> version(InstallUtil::GetChromeVersion(dist, true)); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 289 | if (version.get()) { |
[email protected] | b969648 | 2010-11-30 23:56:18 | [diff] [blame] | 290 | FilePath exe_path; |
| 291 | PathService::Get(base::DIR_EXE, &exe_path); |
| 292 | std::wstring exe = exe_path.value(); |
[email protected] | bf6117c7e | 2010-12-01 06:00:25 | [diff] [blame] | 293 | FilePath user_exe_path(installer::GetChromeInstallPath(false, dist)); |
| 294 | if (FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) { |
[email protected] | 0f26d7b | 2011-01-05 19:10:44 | [diff] [blame] | 295 | const string16 text = |
| 296 | l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT); |
| 297 | const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 298 | const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST; |
[email protected] | 75b6805 | 2011-02-03 06:01:16 | [diff] [blame] | 299 | ui::MessageBox(NULL, text, caption, flags); |
[email protected] | e5fbd496 | 2011-02-11 16:30:43 | [diff] [blame] | 300 | CommandLine uninstall_cmd( |
| 301 | InstallUtil::GetChromeUninstallCmd(false, dist->GetType())); |
| 302 | if (!uninstall_cmd.GetProgram().empty()) { |
[email protected] | 74ca044 | 2010-12-15 14:44:50 | [diff] [blame] | 303 | uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall); |
[email protected] | e6124ad5 | 2010-11-15 04:17:52 | [diff] [blame] | 304 | uninstall_cmd.AppendSwitch( |
[email protected] | 74ca044 | 2010-12-15 14:44:50 | [diff] [blame] | 305 | installer::switches::kDoNotRemoveSharedItems); |
[email protected] | e599218 | 2011-07-15 16:47:02 | [diff] [blame] | 306 | base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL); |
[email protected] | 5c9587c | 2008-12-09 21:20:16 | [diff] [blame] | 307 | } |
| 308 | return true; |
| 309 | } |
| 310 | } |
| 311 | return false; |
| 312 | } |