detect Windows version in python

Recently I wrote an application which needs Visual C++ 9.0 Runtime (Or Visual C++ 2008 Redistributable) installed. To make this application more friendly to users, detecting Visual C++ Runtime is added to beginning of program. If Visual C++ runtime is not installed on user's operating system, program will download and install it automatically.

But another problem came, Visual C++ 9.0 Runtime is shipped with Windows 7, we cannot detect whether it's installed just by scanning registry keys. One solution is to detect Windows version first, if Windows version is equal or later than Windows 7, then my application need not concern C++ Runtime things anymore

 

In general there are two ways to get windows version in python, one is using getwindowsversion() method of sys module, the other is through platform() method of platform module.

sys.getwindowsversion()

sys.getwindowsversion()

On my windows 7 machine, Running above code in interactive python interpreter will give me following results:

sys.getwindowsversion(major=6, minor=1, build=7600, platform=2, service_pack='')

First let's look at platform value, platform=2 means that currently running system is Windows NT platform.

Combining major value and minor value can determine a specific version of system. e.g. Windows NT 6.0 (major value 6 and minor value 0) means Windows Vista or Windows 2008, Windows NT 6.1 shown above tells us it's Windows 7 or Windows 2008 R2.

You can view this page for a complete reference of Windows operating systems and their responding major version and minor version.

platform module

platform.platform()

will give us an descriptive string:

'Windows-7-6.1.7600'

Let me explain it in details: Windows-7 is the operating system name well known between users, following 6.1.7600 is meaning major version is 6, minor version is 1 and build No. is 7600

Compared with sys.getwindowsversion(), platform() method is more friendly:)

 

NSIS delete registry value

I searched "nsis delete registry value" on google, but found that search results are not really helpful. So I decide to write this post to introduce how to delete registry value (or how to delete registry string).

Deleting registry value need use DeleteRegValue instruction

DeleteRegValue root_key sub_key value_name

If I need to delete a value named "DisplayName" under "HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\Pooler" (This is the entry name in Add/Remove Programs in Windows XP or Program & Features in Windows 7/8), I could use:

DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pooler" "DisplayName"

And we can check this value by using ReadRegStr and MessageBox:

ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pooler" "DisplayName"

MessageBox MB_OK $0

 

Have fun with NSIS!

pygtk gobject.timeout_add() won’t work after calling gtk.threads_init() on windows xp

I have a pygtk program which starts a separate thread to receive HTTP request from user and display message dialogs by checking a string variable every 500 ms. It works well on Windows 7, but testing on Windows XP failed: the GUI blocked and no window is showed.

Gradually I found gobject.timeout_add() function is not working, in fact, it didn't work after calling gtk.threads_init().I reduced unrelated code and got following simplest situation to reproduce the issue.

Following simple code will hang forever on windows XP, and the "check dialog" text is never outputted to console. The window created in the code showed but is blocked (when I move mouse into the window area, the mouse pointer is always a "loading" icon)

If we remove gtk.threads_init(), code will work.

To solve this issue, just replace gtk.threads_init() with gobject.threads_init()

NSIS start program automatically when Windows starts

I was asked to build a program that monitors employees' actions (e.g. which website is he viewing), it's used to send user actions logs, network requests logs, etc.  to center logging server. But I cannot ask user to run a program which will log their actions, so to start program automatically when Windows starts is necessary.

 

In summary, there are three methods to achieve this:

1. Add program to Run or RunOnce Key

2. Add program shortcut to Start Menu/Startup Folder

3. Register program as a service (But our program is a GUI application and Windows Service doesn't allow GUI, so we ignore this method)

 

Run/RunOnce Key

If the program path is written into Run key, then this program will start every time when System boots.

registry_run

We can write it into HKLM(HKEY_LOCAL_MACHINE) or HKCU(HKEY_CURRENT_USER), HKLM will apply settings to ALL users, while HKCU only applies settings to current user.

WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "Monitor" "X:\Monitor.exe"

WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "Monitor" "X:\Monitor.exe"

RunOnce key will only run program automatically when the system boots first time. And after Windows is loaded, entries under RunOnce will be removed (It's usually used when application needs configuration after system reboots).

 

Start Menu/Startup Folder

Actually, programs under Start Menu/Startup Folder will be started after those defined in "Run" key.

CreateShortCut "$SMSTARTUP\Monitor.lnk" "$INSTDIR\Monitor.exe"

 

Loading order of Run, RunOnce, StartUp folder

Programs defined in Run, RunOnce or StartUp will be loaded in following order:

(Login Screen)

HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\Software\Microsoft\Windows\CurrentVersion\Run
HKCU\Software\Microsoft\Windows\CurrentVersion\Run
StartUp Folder
HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce

 

NSIS sidebar image not displayed

I want to add sidebar image to finish page of a NSIS installer, because the default empty area on the left side is too ugly:)

After reading documentation, I found that MUI_WELCOMEFINISHPAGE_BITMAP is used to specify sidebar image for both welcome page and finish page

Ok, after trying add it to installer script, I found it didn't work at all. Following is the source code

!include "MUI2.nsh"

!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-nsis.bmp"

!insertmacro MUI_PAGE_FINISH

Section
SectionEnd

Finally I found that !insertmacro MUI_LANGUAGE "English" is needed, and it must be placed after !insertmacro MUI_PAGE_*. (please check here)

So following code will work:

!include "MUI2.nsh"

!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-nsis.bmp"

!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_LANGUAGE "English"

Section
SectionEnd

But following code will not work:

!include "MUI2.nsh"

!define MUI_WELCOMEFINISHPAGE_BITMAP "${NSISDIR}\Contrib\Graphics\Wizard\orange-nsis.bmp"

!insertmacro MUI_LANGUAGE "English"

!insertmacro MUI_PAGE_FINISH

Section
SectionEnd

 

And if MUI_LANGUAGE is not defined, some text will not be displayed correctly in the installer.

Also MUI_WELCOMEFINISHPAGE_BITMAP will add sidebar image to Welcome page

How to use git-ftp on Windows

Background

Before introducing how to use git-ftp on windows, I want to tell some story.

Two years ago, I used Filezilla and ftp to deploy websites. If some files are changed, I have to upload these files manually again. Finding changed files is a time-wasting progress, I have to say. But worse thing is sometimes I forgot which files are changed and I didn't upload all changed files. Then client saw the website is broken and complained to me. It's really painful..

Later I heard about git and started learning it. Using git to deploy is a happy progress. I don't need to find changed files or upload them one by one manually.

But what if some cheap web hosting solutions don't support ssh or git? Finally I found git-ftp

 

What is git-ftp?

Git-ftp is a deployment tool to deploy your changed files which are tracked by git. It's useful because some web hosting companies don't support ssh or git, but only FTP.

But git-ftp is a Linux shell script, so we need to install cygwin to run this script on windows.

 

Requirements

  • Download git-ftp from GitHub
  • Download msysgit from Google Code, and make sure you check "add msysgit path to PATH environment variable" option during installation.
  • Cygwin
    Cygwin is a command line environment providing common Linux tools
    Download cygwin from here, install it using default options.

 

After Installation

Then open cygwin from desktop or start menu, go to the directory containing git-ftp script file (the drives are under /cygdrive directory, such as /cygdrive/c, /cygdrive/d, etc.)

cd /cygdrive/d/Downloads/git-ftp-0.8.4.0

And make git-ftp script file executale

chmod +x git-ftp

Next copy it to /bin directory so that you can run it from anywhere

cp git-ftp /bin

 

Now it's done, Let's run it!

Initialization

Since this is the first time we use it, we need to run "git ftp init" for initial push

git ftp init -u foo -p - ftp://example.com/directoryA

This will configure your FTP server with specified host address, user name and password.

git-ftp

git-ftp windows

Pushing

Running following command to push your staged files tracked by git

git ftp push

 

After uploading is done, it will remember this version as last deployment, so if you run "git ftp push" later, it will upload changed files compare to this version and set new version as last deployment.