Why I am here?
- If you like to use open-source Chromium browser instead of more proprietary Google Chrome
- If you don't like manually updating Chromium each time
- If you like to update Chromium from zip archive instead of using installer
- If you are curious what else PowerShell can do for you today))
Introduction
For those of you, not yet familiar with Chromium browser, let me introduce it quickly.
Chromium project is a fully open-source effort supported by Google and extensive community to build a base for Google's proprietary Google Chrome browser.
Basically, here is how it works. Chromium project constantly releases updates. Google then takes them, tests them to be stable, polishes them, and adds some proprietary code, like built-in PDF reader, various media format support, and automated updater.
So, people who prefer Google not to collect any information on them, or preferring fully open-source software, or simply desiring to always have latest, best, and fastest version of the browser - use Chromium instead of Chrome.
During the time I used Chromium, the only thing about it I found particularly annoying, was a need to update it manually all the time. It was even more frustrating, since I preferred to update it from a zip archive instead of using an installer (which also enjoyed clearing your user profile). Also I didn't want any changes to Windows (except a user profile it creates) be done, but wanted to control program's location on the hard drive.
There was simply too many annoying steps involved:
- Open to the list of Chromium builds downloads
- Close any open instances of Chromium
- Open top build (with the latest version) directory
- Click on 'chrome-win32.zip' to download archive with the browser
- On the computer, delete directory with previous Chromium version
- Extract 'chrome-win32.zip' contents
- Delete source 'chrome-win32.zip'
So I desperately needed to limit that process to as little as one click, and thus my quest had begun!
Background
It would be beneficial if you are already familiar with PowerShell basics and got your system ready to run PowerShell scripts (.ps1 files), and if not, you can follow simple instructions here.
If you are not familiar with PowerShell at all, but know some VisualBasic or C#, you'll be fine here too!
Let's see some PowerShell!
I'll go step-by-step about what this script is doing (also you can just download the complete script at the end of this article).
If you want to try this code while reading this article, the best way is use Windows PowerShell ISE, which is a nice script building GUI bundled with PowerShell. On Windows 7/8 you can find it via Start menu search, and on Windows XP it should be located in a directory similar to this: C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe.
It has a nice tabbed interface and code highlighting and allows to see your PoweShell output right away. Let's save the first empty open tab as Chromium_Updater.ps1 (or the name of your choice).
Step 1: Configure update settings
This is the part where you need to configure the settings unique to your system. You can store your local settings directly in script file as variables, but it's better to have them in some external configuration file, so your main script file can be re-used on different systems without modification.
So, what is the easiest way to store those settings? In a PowerShell world it is XML most surely. XML is a first class citizen for PowerShell, hence you'd need to write minimum amount of code to work with XML files:
$xml_document = [xml](get-content Some_XML_File.xml)
That sole line loads contents of your XML file into the memory. And if your XML is similar to this:
<settings>
<property>Value</property>
</settings>
To get that property value 'Value':
$property_value = $xml_document.settings.property
Keeping that in mind, let's create a file name Chromium_Updater_Settings.xml in the same folder with Chromium_Updater.ps1:
<settings type="Chromium_Updater_Settings">
<archive_name>chrome-win32</archive_name>
<archive_ext>.zip</archive_ext>
<download_path></download_path>
<install_path>C:\Programs</install_path>
</settings>
Here archive_name
'chrome-win32' is the deafult name of the zipped Chromium archive provided by Google, and also the name of the sole folder inside that archive, so whereever it's contens are extracted, Chromium will sit inside 'chrome-win32' folder. And archive_ext
is pretty self-explanatory. Then download_path
is the path where archive will be downloaded from Google servers (don't set it yet though). Lastly, install_path
is where contents of chrome-win32.zip should be extracted.
Now lets return to our empty Chromium_Updater.ps1 script, and load settings from the XML file we've just created:
$config = [xml](get-content Chromium_Updater_Settings.xml -ErrorAction SilentlyContinue)
Noticed -ErrorAction SilentlyContinue? What it does, it hides any errors if XML file doesn't exist or corrupted, which means that $config
will become null, so we can check if our XML file was loaded:
if ($config -eq $null) {
""; "Chromium_Updater_Settings.xml file is not found!"
Start-Sleep -s 5; exit
}
This validation basically checks if our local variable $config
is null, and if it is - it displays error message, waits for 5 seconds, then stops the script.
If this validation is passed, we can now load settings from it into local variables:
$chromium_archive_name = $config.settings.archive_name
$chromium_archive_ext = $config.settings.archive_ext
$install_path = $config.settings.install_path + "\"
$download_path = $env:USERPROFILE + "\"
if ($config.settings.download_path) {
$download_path = $config.settings.download_path
}
Here it is pretty straightforward, except for the <code>$<code>download_path
. What is happening here - by default PowerShell sets it the path to default user directory via $env:USERPROFILE
call. If you set custom location in XML file, it'll replace default value with your custom value.
Now we have all the information we need to update/install Chromium on the local computer. But let's add two more helpful variables to be used internally:
$source_archive_path = $download_path + $chromium_archive_name + $chromium_archive_ext
$old_version_path = $install_path + $chromium_archive_name
Since we will simply extract contents of the Chromium archive to a chosen folder, $old_version_path
will include the name of the folder inside source archive - chrome-win32 in this case.
Now, let's proceed to the next step.
Step 2: Download archive with latest Chromium build
Getting the latest Chromium build is a two-step process. First step - to find out the latest build number. And there is a Google url which provides just that:
http://commondatastorage.googleapis.com/chromium-browser-continuous/Win/LAST_CHANGE
Try to run it in your browser, and open it's source code. It's only a plain 6-digit number, which is exactly what we need. Now, to download particular Chromium build, we need to use another url, where we just need to replace [BUILD_NUMBER] with the number we've got from the first url:
http://commondatastorage.googleapis.com/chromium-browser-continuous/Win/[BUILD_NUMBER]/chrome-win32.zip
Knowing that, let's write some PowerShell to check for and download the latest Chromium build. We'll use an instance of .NET System.Web.Client class to interact with the web:
$web = New-Object System.Net.WebClient
$latest_version = $web.DownloadString("http://commondatastorage.googleapis.com/chromium-browser-continuous/Win/LAST_CHANGE")
if ($latest_version) {
$url = "http://commondatastorage.googleapis.com/chromium-browser-continuous/Win/" + $latest_version + "/chrome-win32.zip"
$web.DownloadFile($url, $source_archive_path);
}
Code snippet above is simple - it loads latest build number into variable, checks if the number is not null, then downloads Chromium archive to the path we've setup earlier (by default it is user's home directory).
And that's it for that step.
Step 3: Safely close any open Chromium instances
Now we have the latest archive and all the data to install/update older version. But what if Chromium is already open, and we perform the update? It'll fail, because all Chromium local files will be in use. To avoid this we need to close it first, and do so gently, so Chromium will close nicely, without getting anything corrupted. Luckily, there is a simple command for that:
Get-Process chrome | % { $_.CloseMainWindow() }
Since Chromium has a separate process for each open tab or background process, we'd need to close them all. The command above gets a list of all processes named chrome running in the system, then for each one of them it attempts to close them the same way a user will do when closing program's window or selecting 'exit' inside the application.
Soon enough I realized that doing so will not always get you what you want, especially if you have a lot of tabs open, or any sites that need some time to close. But if you run command above several times, you most sure will get all of Chromium processes to comply with your will. Do so like this:
$attempts = 10
do {
Get-Process chrome | % { $_.CloseMainWindow() | out-null }
Start-Sleep -s 1
$attempts = $attempts - 1
}
until ((Get-Process chrome -ErrorAction SilentlyContinue) -eq $null -Or $attempts -eq 0)
Here is how this DO UNTIL loop works: PowerShell attempts to close all Chromium processes > waits for one second > checks if there no Chromium processes running via Get-Process command > if there are still some processes open, it repeats the attempt until everything is shut down, or number of attempts is met (10 attempts or 10 seconds, in our case).
As for ' | out-null' added after .CloseMainWindow() - it simply hides any output that command produces.
Also, this might surprise you, but Chromium and Google Chrome processes are named the same)) So running Chromium update script will also close your Chrome, if you happen to run both Chrome and Chromium at the same time, of course.
And we're done with this step! Let's go further.
Step 4: Remove old Chromium
So now we are completely ready to perform the update - we have a zip file with latest version, we know where to install it, and we closed all open Chromium windows.
Let's first check if Chromium exists at install location, and delete older version:
if (Test-Path $old_version_path) {
Remove-Item -Recurse -Force $old_version_path
}
Pretty easy, right? Next let's check if the installation directory (path), we've set in our XML file, exists, and if not, let's create it using PowerShell's New-Item command:
if ((Test-Path $install_path) -eq $false) {
New-Item $install_path -type directory
}
That check above would be relevant only first time we run this script - when new Chromium is installed.
Let's move on to next step.
Step 5: Extract new version of Chromium
Now let's extract 'chrome-win32.zip' archive we downloaded earlier. Unfortunately PowerShell doesn't have built-in methods to work with zip files. However Windows does! So we're going to use it to silently extract our zip file. Here is the code:
$zip_file_path = $source_archive_path
$unzip_path = $install_path
if (Test-Path $zip_file_path) {
[System.Int32]$yestoall = "16"
[System.Int32]$progressbar = "4"
$shellApplication = New-Object -com shell.application
$zipPackage = $shellApplication.NameSpace($zip_file_path)
$destinationFolder = $shellApplication.NameSpace($unzip_path)
$destinationFolder.CopyHere($zipPackage.Items(), $progressbar)
}
In this code - $yestoall = "16"
means that no interaction will be required from user, while $progressbar = "4"
hides progress window (which usually pops up when this code is executed).
Now we're almost done, let's move to the last step.
Step 6: Create desktop shortcut
Yeah, to make it even easier, let's avoid clicking through some folders to start Chromium, by creating a simple desktop shortcut to our installation:
$wshshell = New-Object -ComObject WScript.Shell
$lnk = $wshshell.CreateShortcut("$env:USERPROFILE\Desktop\Chromium.lnk")
$lnk.TargetPath = "$old_version_path\chrome.exe"
$lnk.WorkingDirectory = "$old_version_path"
$lnk.Save()
Once again we have to use Windows to aid us, since there is no built-in PowerShell methods to create shortcuts.
And we're done - our Chromium-Updater script is ready to go!
Review
Let's review the process we've implemented in this script:
- Local settings from XML file are loaded
- Latest Chromium build is downloaded
- If Chromium is open, all instances are safely closed
- Old version of Chromium is removed
- Latest Chromium build is extracted from zip archive
- Desktop shortcut to Chromium is created
Also remember that during the update/install process this script won't need any input from user, thus making it easy to use and ideal to be run on schedule, so you can forget about updating your Chromium manually ever again!
Downloads
The final script contains all pieces of code described above, but additionally wrapped into nice IF statements with some fool-proof logic and smart update progress messages.
And of course you can
to always get the latest stuff!
Future Plans
- Show download/zip extraction progress inside console
- Add option to select which build number to download
- Select between Continuous (stable) and Snapshot builds of Chromium
- Add Chromium uninstaller script
History
- 7/19/2012 - Initial article released along with v.1.0 of Chromium-Updater