blob: b59572fa5111d15d7771619fa452145188ea5ee4 [file] [log] [blame]
[email protected]a173cc92009-08-20 23:26:371// Copyright (c) 2009 The Chromium Authors. All rights reserved.
[email protected]5c9587c2008-12-09 21:20:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]1152b7e2009-09-14 03:26:035#include "chrome/browser/browser_main.h"
[email protected]5c9587c2008-12-09 21:20:166#include "chrome/browser/browser_main_win.h"
7
[email protected]4a0765a2009-05-08 23:12:258#include <windows.h>
9#include <shellapi.h>
10
[email protected]a92b8642009-05-05 23:38:5611#include "app/l10n_util.h"
[email protected]37126212009-05-06 02:23:3112#include "app/message_box_flags.h"
[email protected]4a0765a2009-05-08 23:12:2513#include "app/win_util.h"
[email protected]5c9587c2008-12-09 21:20:1614#include "base/command_line.h"
15#include "base/path_service.h"
16#include "base/win_util.h"
[email protected]5c9587c2008-12-09 21:20:1617#include "chrome/browser/first_run.h"
[email protected]cd1adc22009-01-16 01:29:2218#include "chrome/browser/metrics/metrics_service.h"
[email protected]a173cc92009-08-20 23:26:3719#include "chrome/browser/views/uninstall_view.h"
[email protected]5c9587c2008-12-09 21:20:1620#include "chrome/common/chrome_switches.h"
21#include "chrome/common/env_vars.h"
[email protected]74d1bb02009-03-03 00:41:2322#include "chrome/common/result_codes.h"
[email protected]5c9587c2008-12-09 21:20:1623#include "chrome/installer/util/helper.h"
24#include "chrome/installer/util/install_util.h"
25#include "chrome/installer/util/shell_util.h"
[email protected]34ac8f32009-02-22 23:03:2726#include "grit/chromium_strings.h"
27#include "grit/generated_resources.h"
[email protected]148d1052009-07-31 22:53:3728#include "views/focus/accelerator_handler.h"
[email protected]2362e4f2009-05-08 00:34:0529#include "views/window/window.h"
[email protected]5c9587c2008-12-09 21:20:1630
[email protected]1152b7e2009-09-14 03:26:0331namespace Platform {
32
33void WillInitializeMainMessageLoop(const MainFunctionParams& parameters) {
34}
35
36void WillTerminate() {
37}
38
39void RecordBreakpadStatusUMA(MetricsService* metrics) {
40 DWORD len = ::GetEnvironmentVariableW(env_vars::kNoOOBreakpad, NULL, 0);
41 metrics->RecordBreakpadRegistration((len == 0));
42 metrics->RecordBreakpadHasDebugger(TRUE == ::IsDebuggerPresent());
43}
44
45} // namespace Platform
46
[email protected]5c9587c2008-12-09 21:20:1647// Displays a warning message if the user is running chrome on windows 2000.
48// Returns true if the OS is win2000, false otherwise.
49bool CheckForWin2000() {
50 if (win_util::GetWinVersion() == win_util::WINVERSION_2000) {
51 const std::wstring text = l10n_util::GetString(IDS_UNSUPPORTED_OS_WIN2000);
52 const std::wstring caption = l10n_util::GetString(IDS_PRODUCT_NAME);
53 win_util::MessageBox(NULL, text, caption,
54 MB_OK | MB_ICONWARNING | MB_TOPMOST);
55 return true;
56 }
57 return false;
58}
59
[email protected]4df8786f2009-04-17 13:24:5760int AskForUninstallConfirmation() {
61 int ret = ResultCodes::NORMAL_EXIT;
[email protected]a173cc92009-08-20 23:26:3762 views::Window::CreateChromeWindow(NULL, gfx::Rect(),
63 new UninstallView(ret))->Show();
[email protected]047f6222009-07-29 23:34:5664 views::AcceleratorHandler accelerator_handler;
65 MessageLoopForUI::current()->Run(&accelerator_handler);
[email protected]4df8786f2009-04-17 13:24:5766 return ret;
[email protected]5c9587c2008-12-09 21:20:1667}
68
[email protected]53c38d232009-02-13 20:52:1869void ShowCloseBrowserFirstMessageBox() {
70 const std::wstring text = l10n_util::GetString(IDS_UNINSTALL_CLOSE_APP);
71 const std::wstring caption = l10n_util::GetString(IDS_PRODUCT_NAME);
72 const UINT flags = MB_OK | MB_ICONWARNING | MB_TOPMOST;
73 win_util::MessageBox(NULL, text, caption, flags);
74}
75
76int DoUninstallTasks(bool chrome_still_running) {
[email protected]a173cc92009-08-20 23:26:3777 // We want to show a warning to user (and exit) if Chrome is already running
78 // *before* we show the uninstall confirmation dialog box. But while the
79 // uninstall confirmation dialog is up, user might start Chrome, so we
80 // check once again after user acknowledges Uninstall dialog.
[email protected]53c38d232009-02-13 20:52:1881 if (chrome_still_running) {
82 ShowCloseBrowserFirstMessageBox();
83 return ResultCodes::UNINSTALL_CHROME_ALIVE;
84 }
[email protected]4df8786f2009-04-17 13:24:5785 int ret = AskForUninstallConfirmation();
[email protected]a173cc92009-08-20 23:26:3786 if (Upgrade::IsBrowserAlreadyRunning()) {
87 ShowCloseBrowserFirstMessageBox();
88 return ResultCodes::UNINSTALL_CHROME_ALIVE;
89 }
90
[email protected]4df8786f2009-04-17 13:24:5791 if (ret != ResultCodes::UNINSTALL_USER_CANCEL) {
92 // The following actions are just best effort.
93 LOG(INFO) << "Executing uninstall actions";
94 if (!FirstRun::RemoveSentinel())
95 LOG(INFO) << "Failed to delete sentinel file.";
96 // We want to remove user level shortcuts and we only care about the ones
97 // created by us and not by the installer so |alternate| is false.
98 if (!ShellUtil::RemoveChromeDesktopShortcut(ShellUtil::CURRENT_USER, false))
99 LOG(INFO) << "Failed to delete desktop shortcut.";
100 if (!ShellUtil::RemoveChromeQuickLaunchShortcut(ShellUtil::CURRENT_USER))
101 LOG(INFO) << "Failed to delete quick launch shortcut.";
102 }
[email protected]5c9587c2008-12-09 21:20:16103 return ret;
104}
105
106// Prepares the localized strings that are going to be displayed to
107// the user if the browser process dies. These strings are stored in the
108// environment block so they are accessible in the early stages of the
109// chrome executable's lifetime.
110void PrepareRestartOnCrashEnviroment(const CommandLine &parsed_command_line) {
111 // Clear this var so child processes don't show the dialog by default.
112 ::SetEnvironmentVariableW(env_vars::kShowRestart, NULL);
113
114 // For non-interactive tests we don't restart on crash.
115 if (::GetEnvironmentVariableW(env_vars::kHeadless, NULL, 0))
116 return;
117
118 // If the known command-line test options are used we don't create the
119 // environment block which means we don't get the restart dialog.
120 if (parsed_command_line.HasSwitch(switches::kBrowserCrashTest) ||
121 parsed_command_line.HasSwitch(switches::kBrowserAssertTest) ||
122 parsed_command_line.HasSwitch(switches::kNoErrorDialogs))
123 return;
124
125 // The encoding we use for the info is "title|context|direction" where
126 // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending
127 // on the current locale.
128 std::wstring dlg_strings;
129 dlg_strings.append(l10n_util::GetString(IDS_CRASH_RECOVERY_TITLE));
130 dlg_strings.append(L"|");
131 dlg_strings.append(l10n_util::GetString(IDS_CRASH_RECOVERY_CONTENT));
132 dlg_strings.append(L"|");
133 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT)
134 dlg_strings.append(env_vars::kRtlLocale);
135 else
136 dlg_strings.append(env_vars::kLtrLocale);
137
138 ::SetEnvironmentVariableW(env_vars::kRestartInfo, dlg_strings.c_str());
139}
140
141// This method handles the --hide-icons and --show-icons command line options
142// for chrome that get triggered by Windows from registry entries
143// HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons
144// functionality so we just ask the users if they want to uninstall Chrome.
145int HandleIconsCommands(const CommandLine &parsed_command_line) {
146 if (parsed_command_line.HasSwitch(switches::kHideIcons)) {
147 std::wstring cp_applet;
[email protected]309c8ff2009-02-25 20:26:44148 win_util::WinVersion version = win_util::GetWinVersion();
149 if (version >= win_util::WINVERSION_VISTA) {
[email protected]5c9587c2008-12-09 21:20:16150 cp_applet.assign(L"Programs and Features"); // Windows Vista and later.
[email protected]309c8ff2009-02-25 20:26:44151 } else if (version >= win_util::WINVERSION_XP) {
[email protected]5c9587c2008-12-09 21:20:16152 cp_applet.assign(L"Add/Remove Programs"); // Windows XP.
153 } else {
154 return ResultCodes::UNSUPPORTED_PARAM; // Not supported
155 }
156
157 const std::wstring msg = l10n_util::GetStringF(IDS_HIDE_ICONS_NOT_SUPPORTED,
158 cp_applet);
159 const std::wstring caption = l10n_util::GetString(IDS_PRODUCT_NAME);
160 const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST;
161 if (IDOK == win_util::MessageBox(NULL, msg, caption, flags))
162 ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL);
163 return ResultCodes::NORMAL_EXIT; // Exit as we are not launching browser.
164 }
165 // We don't hide icons so we shouldn't do anything special to show them
166 return ResultCodes::UNSUPPORTED_PARAM;
167}
168
169// Check if there is any machine level Chrome installed on the current
170// machine. If yes and the current Chrome process is user level, we do not
171// allow the user level Chrome to run. So we notify the user and uninstall
172// user level Chrome.
173bool CheckMachineLevelInstall() {
174 scoped_ptr<installer::Version> version(InstallUtil::GetChromeVersion(true));
175 if (version.get()) {
176 std::wstring exe;
177 PathService::Get(base::DIR_EXE, &exe);
178 std::transform(exe.begin(), exe.end(), exe.begin(), tolower);
179 std::wstring user_exe_path = installer::GetChromeInstallPath(false);
180 std::transform(user_exe_path.begin(), user_exe_path.end(),
181 user_exe_path.begin(), tolower);
182 if (exe == user_exe_path) {
183 const std::wstring text =
184 l10n_util::GetString(IDS_MACHINE_LEVEL_INSTALL_CONFLICT);
185 const std::wstring caption = l10n_util::GetString(IDS_PRODUCT_NAME);
186 const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST;
187 win_util::MessageBox(NULL, text, caption, flags);
188 std::wstring uninstall_cmd = InstallUtil::GetChromeUninstallCmd(false);
189 if (!uninstall_cmd.empty()) {
190 uninstall_cmd.append(L" --");
191 uninstall_cmd.append(installer_util::switches::kForceUninstall);
192 uninstall_cmd.append(L" --");
193 uninstall_cmd.append(installer_util::switches::kDoNotRemoveSharedItems);
194 base::LaunchApp(uninstall_cmd, false, false, NULL);
195 }
196 return true;
197 }
198 }
199 return false;
200}
201
202bool DoUpgradeTasks(const CommandLine& command_line) {
203 if (!Upgrade::SwapNewChromeExeIfPresent())
204 return false;
205 // At this point the chrome.exe has been swapped with the new one.
206 if (!Upgrade::RelaunchChromeBrowser(command_line)) {
207 // The re-launch fails. Feel free to panic now.
208 NOTREACHED();
209 }
210 return true;
211}