How to update Chromium when an instance of it is running?

235 views
Skip to first unread message

Asesh Shrestha

unread,
Jan 3, 2017, 6:45:13 AM1/3/17
to Chromium-dev
I am working on updating our Chromium fork. Omaha will automatically download and install updates for our fork right now. When no instance of our fork is running then it will simply replace the old version of our fork but when an instance is running then it will install new version but however it won't be activated as can be seen in the screen shot below:


In this case workstream.exe us running on our machine. But even if I close workstream.exe and start it again, the old version won't be replaced by the new version. 


When this happens, after debugging mini_installer.exe and setup.exe I have noticed it creates a registry key here: HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\CloudFactory\Update\Clients\{F797A2A7-ABEE-4B88-B9A9-FB230284BEEE} and on the right pane: cmd's value will be "C:\Program Files (x86)\CloudFactory\WorkStream\Application\55.2.2883.95\Installer\setup.exe" --rename-chrome-exe --system-level --verbose-logging as can be seen below:




If the above command is manually executed then new version of Chrome will replace the old version, that's what we want. But who is responsible for executing that command? Will Omaha do it or Chromium? Is Chromium supposed to do so after a new instance of Chromium is launched? I have been debugging through Chromium source code (WorkStream.exe) but looks like it doesn't do so. We want our browser to be replaced with new version after the user closes the browser just like Chrome does. Can someone give me a pointer on how to do it? 


Thanks


Asesh Shrestha

unread,
Jan 3, 2017, 7:05:26 AM1/3/17
to Chromium-dev
Just wanted to add that the updater (mini_installer.exe) won't do so. setup.exe will install the new version and return IN_USE_UPDATED after doing so

Greg Thompson

unread,
Jan 3, 2017, 8:38:48 AM1/3/17
to asesh.s...@cloudfactory.com, Chromium-dev
Look into SwapNewChromeExeIfPresent. It is supposed to invoke the rename dance during browser shutdown and/or startup when needed.

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Asesh Shrestha

unread,
Jan 4, 2017, 2:17:47 AM1/4/17
to Chromium-dev, asesh.s...@cloudfactory.com
Thanks, looks like it will try to do so when launching/exiting Chrome. Our browser is 64-bit but however it stores registry keys in WOW6432 node but it was not searching there. I have fixed it but since setup.exe requires elevated privilege but won't have one when Chromium executes it. So it invokes Google update for renaming. I will have to work on it. Thanks again

Asesh Shrestha

unread,
Jan 4, 2017, 3:24:40 AM1/4/17
to Chromium-dev, asesh.s...@cloudfactory.com
Looks like Google hasn't open sourced "google_update/google_update_idl.h". I can't find it in Chromium source code. Looks like the implementation of IProcessLauncher in InvokeGoogleUpdateForRename depends on that header file. Maybe I am missing something? It's not part of Omaha either.


On Tuesday, January 3, 2017 at 7:23:48 PM UTC+5:45, Greg Thompson wrote:

Greg Thompson

unread,
Jan 5, 2017, 4:54:42 AM1/5/17
to asesh.s...@cloudfactory.com, Chromium-dev
https://chromium.googlesource.com/chromium/src/+/master/google_update/README.chromium mentions that google_update_idl.idl comes from the open source Omaha project, which is now on GitHub. Looking there, you will find that IProcessLauncher is a part of Omaha: see https://github.com/google/omaha/blob/master/omaha/goopdate/omaha3_idl.idl.

Asesh Shrestha

unread,
Jan 5, 2017, 5:18:11 AM1/5/17
to Chromium-dev, asesh.s...@cloudfactory.com
Thanks for replying. I found out that it's part of Chromium project too and it's located here: src\google_update\google_update_idl.idl

I did compile that file with Microsoft midl compiler and included #include "google_update/google_update_idl.h" and it runs. But when it invokes:

 HRESULT hCmdElevated = (process_launcher->LaunchCmdElevated(dist->GetAppGuid().c_str(),
 google_update::kRegRenameCmdField,
 current_process_id,
 &phandle));

it will always fail and the value of hCmdElevated will be "DB_E_ROWLIMITEXCEEDED Row could not be inserted into the rowset without exceeding provider's maximum number of active rows.". I can't step into the source code either. Looks like the parameters passed to it are ok. I do have Chrome installed and our Omaha client which is a fork of Omaha both have the same GUID. So does it matter? Looks like that method is supposed to invoke the value of cmd with elevated privilege via Omaha. Can you please tell me what should I do? I can't find the source code of LaunchCmdElevated though I can only find it's COM interface

Greg Thompson

unread,
Jan 5, 2017, 6:05:10 AM1/5/17
to asesh.s...@cloudfactory.com, Chromium-dev
You are using your own modified version of Omaha, correct? If so, you must use the .idl file from your own Omaha fork (which should have distinct class and interface GUIDs so that it does not collide with Google Update or other parties' ports of Omaha). I suggest you make your own "src/your_updater/" directory and more-or-less mirror what you find in "src/google_update", then modify src/chrome/browser/BUILD.gn so that your "browser" target has a dependency on your_updater much like it has one on google_update for a Google Chrome-branded build.

I suggest you connect with whomever in your organization is in charge of your own fork of Omaha.

Asesh Shrestha

unread,
Jan 5, 2017, 6:11:39 AM1/5/17
to Chromium-dev, asesh.s...@cloudfactory.com
Thanks for replying. I will look at it and let you know the result

Asesh Shrestha

unread,
Jan 6, 2017, 10:22:59 AM1/6/17
to Chromium-dev, asesh.s...@cloudfactory.com
I have finally managed to fix it. We had to change the GUID of Omaha (fork) and also had to replace Chromium's and Omaha's GUID with ours in src/chrome/installer/util/google_update_constants.cc 

Then I copied that idl file from our Omaha fork and placed it in src\google_update and renamed it to google_update_idl.idl. You will also have to compile it before building chrome or mini_installer. Use this command: ninja -C out\YourBuildFolder google_update to do so

You should also place this code (or uncomment GOOGLE_CHROME_BUILD) inside src/chrome/browser/first_run/upgrade_util_win.cc @InvokeGoogleUpdateForRename

base::win::ScopedComPtr<IProcessLauncher> process_launcher;
if (SUCCEEDED(process_launcher.CreateInstance(__uuidof(ProcessLauncherClass))))
{
ULONG_PTR phandle = NULL;
DWORD current_process_id = ::GetCurrentProcessId();
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
HRESULT hCmdElevated = process_launcher->LaunchCmdElevated(dist->GetAppGuid().c_str(),
google_update::kRegRenameCmdField,
current_process_id,
&phandle);
if(SUCCEEDED(hCmdElevated))
{
HANDLE handle = HANDLE(phandle);
::WaitForSingleObject(handle, INFINITE);
DWORD exit_code;
::GetExitCodeProcess(handle, &exit_code);
::CloseHandle(handle);
if (exit_code == installer::RENAME_SUCCESSFUL)
return true;
}
}

That's it. While debugging I noticed the GUID of IProcessLauncher was different from that of our Omaha fork which is specified in idl file. Just a suggestion, it's better to use SUCCEEDED macro as opposed to using more confusing !FAILED macro. LaunchCmdElevated was actually returning 0x80040E01 but a bug in VS debugger actually shows different value as I had mentioned above, even the disassembled code shown is not correct. 0x80040E01  was actually being returned by ObjectStublessClient in combase.dll.

Thanks again :)

Greg Thompson

unread,
Jan 6, 2017, 10:34:12 AM1/6/17
to asesh.s...@cloudfactory.com, Chromium-dev
On Fri, Jan 6, 2017 at 4:23 PM Asesh Shrestha <asesh.s...@cloudfactory.com> wrote:
I have finally managed to fix it. We had to change the GUID of Omaha (fork) and also had to replace Chromium's and Omaha's GUID with ours in src/chrome/installer/util/google_update_constants.cc 

Then I copied that idl file from our Omaha fork and placed it in src\google_update and renamed it to google_update_idl.idl. You will also have to compile it before building chrome or mini_installer. Use this command: ninja -C out\YourBuildFolder google_update to do so

You can avoid needed to do things like this manually by updating your local src/chrome/browser/BUILD.gn so that the "browser" target depends on the "google_update" target.

Patches are welcome to make it easier for Chromium forks to integrate with their own dedicated Omaha forks.



You should also place this code (or uncomment GOOGLE_CHROME_BUILD) inside src/chrome/browser/first_run/upgrade_util_win.cc @InvokeGoogleUpdateForRename

base::win::ScopedComPtr<IProcessLauncher> process_launcher;
if (SUCCEEDED(process_launcher.CreateInstance(__uuidof(ProcessLauncherClass))))
{
ULONG_PTR phandle = NULL;
DWORD current_process_id = ::GetCurrentProcessId();
BrowserDistribution* dist = BrowserDistribution::GetDistribution();
HRESULT hCmdElevated = process_launcher->LaunchCmdElevated(dist->GetAppGuid().c_str(),
google_update::kRegRenameCmdField,
current_process_id,
&phandle);
if(SUCCEEDED(hCmdElevated))
{
HANDLE handle = HANDLE(phandle);
::WaitForSingleObject(handle, INFINITE);
DWORD exit_code;
::GetExitCodeProcess(handle, &exit_code);
::CloseHandle(handle);
if (exit_code == installer::RENAME_SUCCESSFUL)
return true;
}
}

That's it. While debugging I noticed the GUID of IProcessLauncher was different from that of our Omaha fork which is specified in idl file. Just a suggestion, it's better to use SUCCEEDED macro as opposed to using more confusing !FAILED macro.

Patches are welcome. :-)
Reply all
Reply to author
Forward
0 new messages