Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/engine/Updater.cpp

Issue 10920006: Expect MSI installers (Closed)
Patch Set: Created June 10, 2013, 3:27 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <functional> 1 #include <functional>
2 #include <memory> 2 #include <memory>
3 #include <sstream> 3 #include <sstream>
4
5 #include <Windows.h>
6 #include <Msi.h>
7
4 #include <AdblockPlus/FileSystem.h> 8 #include <AdblockPlus/FileSystem.h>
5 #include <AdblockPlus/WebRequest.h> 9 #include <AdblockPlus/WebRequest.h>
6 10
7 #include "../shared/Dictionary.h" 11 #include "../shared/Dictionary.h"
8 #include "../shared/Utils.h" 12 #include "../shared/Utils.h"
9 #include "Debug.h" 13 #include "Debug.h"
10 #include "Resource.h" 14 #include "Resource.h"
11 #include "Updater.h" 15 #include "Updater.h"
12 16
13 namespace 17 namespace
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 81
78 DWORD RunThread(LPVOID param) 82 DWORD RunThread(LPVOID param)
79 { 83 {
80 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy pe*>(param)); 84 std::auto_ptr<ThreadCallbackType> callback(reinterpret_cast<ThreadCallbackTy pe*>(param));
81 (*callback)(); 85 (*callback)();
82 return 0; 86 return 0;
83 } 87 }
84 } 88 }
85 89
86 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url) 90 Updater::Updater(AdblockPlus::JsEnginePtr jsEngine, const std::string& url)
87 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.exe") 91 : jsEngine(jsEngine), url(url), tempFile(GetAppDataPath() + L"\\update.msi")
88 { 92 {
89 } 93 }
90 94
91 void Updater::Update() 95 void Updater::Update()
92 { 96 {
93 Debug("Update available: " + url); 97 Debug("Update available: " + url);
94 98
95 if (DialogBox(NULL, MAKEINTRESOURCE(IDD_UPDATEDIALOG), GetDesktopWindow(), 99 if (DialogBox(NULL, MAKEINTRESOURCE(IDD_UPDATEDIALOG), GetDesktopWindow(),
96 reinterpret_cast<DLGPROC>(&UpdateDlgProc)) == IDOK) 100 reinterpret_cast<DLGPROC>(&UpdateDlgProc)) == IDOK)
97 { 101 {
98 Debug("User accepted update"); 102 Debug("User accepted update");
99 103
100 DialogCallbackType* callback = new DialogCallbackType(std::bind(&Updater::St artDownload,
101 this, std::placeholders::_1));
102 int result = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DOWNLOADDIALOG), GetDe sktopWindow(),
103 reinterpret_cast<DLGPROC>(&DownloadDlgProc),
104 reinterpret_cast<LPARAM>(callback));
105 if (result == DOWNLOAD_FAILED)
106 { 104 {
Felix Dahlke 2013/06/11 10:07:52 I presume the two blocks are to avoid conflicts be
Wladimir Palant 2013/06/11 14:42:10 I would rather have distinct scopes for these two
107 Dictionary* dict = Dictionary::GetInstance(); 105 DialogCallbackType* callback = new DialogCallbackType(std::bind(&Updater:: StartDownload,
108 MessageBoxW(NULL, 106 this, std::placeholders::_1));
109 dict->Lookup("updater", "download-error-neterror").c_str(), 107 int result = DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DOWNLOADDIALOG), Get DesktopWindow(),
110 dict->Lookup("updater", "download-error-title").c_str(), 108 reinterpret_cast<DLGPROC>(&DownloadDlgProc),
111 0); 109 reinterpret_cast<LPARAM>(callback));
110 if (result == DOWNLOAD_FAILED)
111 {
112 Dictionary* dict = Dictionary::GetInstance();
113 MessageBoxW(NULL,
114 dict->Lookup("updater", "download-error-neterror").c_str(),
115 dict->Lookup("updater", "download-error-title").c_str(),
116 0);
117 }
118 if (result != IDOK)
119 return;
112 } 120 }
113 if (result != IDOK)
114 return;
115 121
116 PROCESS_INFORMATION pi; 122 {
117 STARTUPINFO si; 123 UINT result = ::MsiInstallProductW(tempFile.c_str(), L"ACTION=INSTALL INST ALLUILEVEL=2");
Oleksandr 2013/06/10 16:47:56 Wouldn't it be better just to launch like "msiexec
Wladimir Palant 2013/06/11 04:29:56 MsiInstallProduct is IMHO a much cleaner solution
Felix Dahlke 2013/06/11 10:07:52 As long as "update.msi" is hardcoded above we'd ne
Oleksandr 2013/06/11 10:24:49 That's my point. Stuff happens, and maybe for some
Felix Dahlke 2013/06/11 10:28:05 Couldn't we just ship an exe with the msi and exec
Wladimir Palant 2013/06/11 14:42:10 I really don't see why we would need a plan b (one
Felix Dahlke 2013/06/12 13:03:40 I'd vote for two functions then :)
118 ::ZeroMemory(&si, sizeof(si)); 124 if (result != ERROR_SUCCESS)
119 si.cb = sizeof(si); 125 {
120 si.wShowWindow = FALSE; 126 Dictionary* dict = Dictionary::GetInstance();
127 std::wstringstream message;
128 message << dict->Lookup("updater", "download-error-runerror");
129 message << std::endl << L"(error " << result << L")";
130 MessageBoxW(NULL,
131 message.str().c_str(),
132 dict->Lookup("updater", "download-error-title").c_str(),
133 0);
121 134
122 if (!::CreateProcessW(tempFile.c_str(), NULL, NULL, NULL, FALSE, CREATE_BREA KAWAY_FROM_JOB, NULL, NULL, &si, &pi)) 135 std::stringstream error;
123 { 136 error << "Installing update failed (error " << result << ")";
124 Dictionary* dict = Dictionary::GetInstance(); 137 Debug(error.str());
125 MessageBoxW(NULL, 138 return;
126 dict->Lookup("updater", "download-error-runerror").c_str(), 139 }
127 dict->Lookup("updater", "download-error-title").c_str(),
128 0);
129 DebugLastError("Creating updater process failed");
130 return;
131 } 140 }
132 ::CloseHandle(pi.hProcess);
133 ::CloseHandle(pi.hThread);
134 } 141 }
135 } 142 }
136 143
137 void Updater::StartDownload(HWND dialog) 144 void Updater::StartDownload(HWND dialog)
138 { 145 {
139 this->dialog = dialog; 146 this->dialog = dialog;
140 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::RunD ownload, this)); 147 ThreadCallbackType* callback = new ThreadCallbackType(std::bind(&Updater::RunD ownload, this));
141 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread), 148 ::CreateThread(NULL, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(&RunThread),
142 callback, 0, NULL); 149 callback, 0, NULL);
143 } 150 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 } 182 }
176 catch (const std::exception& e) 183 catch (const std::exception& e)
177 { 184 {
178 DebugException(e); 185 DebugException(e);
179 EndDialog(dialog, DOWNLOAD_FAILED); 186 EndDialog(dialog, DOWNLOAD_FAILED);
180 return; 187 return;
181 } 188 }
182 189
183 EndDialog(dialog, IDOK); 190 EndDialog(dialog, IDOK);
184 } 191 }
OLDNEW

Powered by Google App Engine
This is Rietveld