Software Inventory: Firefox Extensions

October 24, 2016


FoxyProxy Standard


Hide My IP


Block site


Video DownloadHelper

Bookmark Management

Go Parent Folder

Show Parent Folder


Quick Locale Switcher

Most of the functionality of previous developer’s extensions Firebug and Web Developer seems to be included in standard Firefox.


Screengrab (fix version)

Session Management

Session Manager


Retrieving the List of Installed Programs in Windows 7

October 14, 2016

The Programs and Features view in the Windows Control Panel does not provide a means to export the list of installed programs as a text file.

A quick web search brought up the information that the information about installed software resides under the registry key


or, on 64-bit systems, under


(Source: social technet, Scripting Guy, HowToGeek, SuperUser)

PowerShell kann enumerate the information under these keys using the Get-ItemProperty commandlet. You can retrieve the PS properties of this data using the Get-Member commandlet.

So the first PS command to retrieve this list is

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*

However, Control Panel does not display the registry entry if

  • its DisplayName is empty or not set
  • its UninstallString is empty or not set

which results in the command

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | 
where-object {$_.DisplayName -and $_.UninstallString }

To retrieve the programs directly in PowerShell ISE, we can simply use the Format-Table commandlet

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | 
Where-Object {$_.DisplayName -and $_.UninstallString } | 
Select-Object Publisher, DisplayName, DisplayVersion, InstallLocation, InstallDate, URLInfoAbout, UninstallString | 
Sort-Object Publisher,DisplayName | 

To output to a file for further processing in Excel, export to a .csv file like this

Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | 
Where-Object {$_.DisplayName -and $_.UninstallString } | 
Select-Object Publisher, DisplayName, DisplayVersion, InstallLocation, InstallDate, URLInfoAbout, UninstallString | 
Sort-Object Publisher,DisplayName | 
Export-Ssv -delimiter "`t" -encoding "unicode" c:\temp\installed.csv

Software Inventory: Chrome Extensions

October 13, 2016


Awesome Screenshot


Full Page Screen Capture

Developer Tools

J CSS Reload

Page load time

Quick Javascript Switcher

Window Resizer

Viewport Dimensions

Tabs and Sessions

Session Buddy

Tab Ahead


The Great Suspender


Google Translator


Finding Deleted IIS Application Directories

October 13, 2016

If you develop web applications for IIS, or administrate IIS and file systems, you sooner or later end up with orphaned IIS application which point to non-existing directories.

To get an overview of IIS applications, start up PowerShell in administrator mode (I prefer PowerShell ISE) and run

import-module webadministration
dir "IIS:\\sites\Default Web Site"

To exclude any files that reside in IIS root, filter out the “file” entries:

import-module webadministration
dir "IIS:\\sites\Default Web Site" | where { $_.NodeType.Trim() -ne "file" }

Finally, we test the Physical Path property of the resulting entries

import-module webadministration
dir "IIS:\\sites\Default Web Site" 
    | where { $_.NodeType.Trim() -ne "file" 
        -and ![System.IO.Directory]::Exists( $_.PhysicalPath ) }

This command lists all IIS web application and virtual root directories which point to non-existing directories. The result looks like this:

Type        Name         Physical Path 
----        ----         ------------- 
application application1 D:\app\app1
application web2         D:\app\web2

Installing the HighlightJS Plugin in Redmine 3.3

July 19, 2016

We wanted to document VBScript code in a Redmine wiki, which ships with a syntax highlighter called CodeRay. There is no VBScript mode in CodeRay, but it can easily be added by copying an existing Scanner and adding and removing some code😉

Unfortunately CodeRay seems to have a problem with symbols with leading ampersands, as documented in this Redmine issue, and VBScript uses &H to indicate hex numbers.

Search brought up the HighlightJS Plugin as an alternative, which I downloaded and copied into the plugins directory.

Unfortunately, Redmine would not start up again.

Looking for the log files, hoping for an indication what goes wrong, I found the file process.log with the following data:

Started GET "/redmine/admin/plugins" for at 2016-07-13 11:46:57 +0200
Processing by AdminController#plugins as HTML
Current user: redadmin (id=1)
Rendered admin/plugins.html.erb within layouts/admin (15.6ms)
Rendered admin/_menu.html.erb (15.6ms)
Rendered layouts/base.html.erb (421.9ms)
Completed 500 Internal Server Error in 625ms (ActiveRecord: 62.5ms)

ActionView::Template::Error (uninitialized constant Highlightjs::Hooks::ViewHighlightedHook::UserAgent):
13: <%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
14: <%= javascript_heads %>
15: <%= heads_for_theme %>
16: <%= call_hook :view_layouts_base_html_head %>
17: <!-- page specific tags -->
18: <%= yield :header_tags -%>
19: </head>
plugins/redmine_highlightjs/lib/hooks/view_highlighted_hook.rb:15:in `view_layouts_base_html_head'
lib/redmine/hook.rb:61:in `block (2 levels) in call_hook'
lib/redmine/hook.rb:61:in `each'
lib/redmine/hook.rb:61:in `block in call_hook'
lib/redmine/hook.rb:58:in `tap'
lib/redmine/hook.rb:58:in `call_hook'
lib/redmine/hook.rb:96:in `call_hook'
app/views/layouts/base.html.erb:16:in `_app_views_layouts_base_html_erb___698415948_43865832'
app/views/layouts/admin.html.erb:8:in `_app_views_layouts_admin_html_erb___707869534_44477868'
lib/redmine/sudo_mode.rb:63:in `sudo_mode'

Now I have no idea how Ruby works, or Redmine, and how to deal with packages and so on. Experimenting with the gem package manager did not fix the situation either.

What I did find though was the location that raised the error, namely checking whether the browser name and version retrieved from the HTTP UserAgent string was among the “supported” browsers. Since it’s hard to imagine that any current browser does not support the highlighting magic of this plugin, I simply deactivated the check in the file view_highlighted_hook.rb:

#user_agent = UserAgent.parse(request)
user_agent = 'MyBrowser'     # don't retrieve, this var is used for logging later

if true            # SupportedBrowsers.detect { |browser| user_agent >= browser }


TypeScript logging with log4javascript in an ASP.Net MVC application

July 12, 2016

I needed to add logging functionality to an existing TypeScript application hosted on ASP.Net MVC.

Since I usually use log4net in C#, log4javascript was an obvious choice, as it provides a similar API.

First, I needed to declare the parts of the log4javascript API I use in TypeScript:

declare module log4javascript {
    class Logger {
        info(msg: string);
        info(msg: string, value: any);
        addAppender(app: AjaxAppender);
    function getLogger(name: string): Logger;
    function getNullLogger(): Logger;
    class AjaxAppender {
        constructor(url: string);
        setSessionId(id: string);
        setLayout(layout: JsonLayout);
        addHeader(key: string, value: string);
    class JsonLayout {
        constructor(readable: boolean, combine: boolean);

In the logging class, I added logger and AjaxAppender. Depending on the data to log, I also configure a JsonLayout.

logger: log4javascript.Logger;

A non-logging logger instance is created using getNullLogger():

this.logger = log4javascript.getNullLogger();

Plain-text AjaxAppender

Use these statements to create an Ajax-based logger in TypeScript:

this.logger = log4javascript.getLogger("MyLoggerName");
var app = new log4javascript.AjaxAppender("http://myhost/myapp/mylogger");

On the MVC side, the controller receives the parameters: logger, timestamp, level, url, message, sessionid, and layout. (Note that these parameter names can be changed using the setKeys() method)

The value for sessionid is set using


To log a string message, simply write"my info log message");

The C# controller method stub therefore looks something like this:

public ActionResult Log(long? timestamp, string level, string sessionid, string message)
    var ipaddr = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (string.IsNullOrEmpty(ipaddr))
        ipaddr = Request.ServerVariables["REMOTE_ADDR"];
    if (string.IsNullOrEmpty(ipaddr))
        ipaddr = Request.UserHostAddress;

    if (level == "INFO")
        logger.Info(ipaddr + " " + sessionid + " " + message);
        logger.Debug("[" + level + "] " + ipaddr + " " + sessionid + " " + message);
    return Json(null);

where logger is an instance of log4net.Ilog.

JSON-formatted AjaxAppender

To change the appender’s data format to JSON, we set its layout to JsonLayout:

this.logger = log4javascript.getLogger("MyJsonLogger");
var app = new log4javascript.AjaxAppender("http://myhost/myapp/myjsonlogger");
app.setLayout(new log4javascript.JsonLayout(false, false));
app.addHeader("Content-Type", "application/json");

The C# controller method receives a JSON array of log entries

            [    "message1",
                "message2", ...

where message1, message2, etc are the parameters of the logger’s debug/info/warn etc. calls.

We create a C# class containing the required properties

public class Data
    public string logger;
    public long? timestamp;
    public string level;
    public string url;
    public string[] message;

and deserialize the HTTP request’s InputStream using JSON.Net:

public ActionResult Execute()
    string inputContent;
    using (var sr = new StreamReader(HttpContext.Request.InputStream))
        inputContent = sr.ReadToEnd();
    var data = JsonConvert.DeserializeObject<Data[]>(inputContent);

    if (data != null)
        foreach (var d in data)
            if (d.level == "INFO")
                logger.Info(d.message[0] + " " + d.message[1]);
                logger.Debug("[" + d.level + "] " + d.message[0] + " " + d.message[1]);
    return Json(null);

Again, logger is an instance of log4net.Ilog.

Installing Bitnami Redmine Stack with Separate Data Directory

July 12, 2016

I downloaded the latest version of the Bitnami Redmine Stack (bitnami-redmine-3.3.0-1-windows-installer.exe) and installed it, which worked without any problems.

However I noticed that the installation does not distinguish between programs/executables and stored data, so I tried to figure out what data is being stored and where.

I found that I only needed to move the MySQL databases to a new data directory. and leave everything else in the installation directory.

First, I created a new location D:\Bitnami-Redmine-data to store Redmine’s data.


Next, I started the Bitnami Redmine Stack Manager Tool and stopped the MySQL Database service.

Bitnami Redmine Stack Manager Tool

Bitnami Redmine Stack Manager Tool

I created a new location D:\Bitnami-Redmine-data to store Redmine’s data, and copied the MySQL data directory C:\Bitnami\redmine-3.3.0-1\mysql\data to D:\Bitnami-Redmine-data\mysql\data.

To let MySQL know about the new location of its databases, I edited C:\Bitnami\redmine-3.3.0-1\mysql\my.ini and changed the [mysqld] section to point to the new directory:



The I started up the MySQL Database service again, which did not raise any errors. Be sure to check the Server Events tab and the Windows Event Log for errors or warnings.


Although the Bitnami Redmine Stack ships with and installs the SVN server svnserve, the installer does not automatically create an SVN repository.

To create an SVN repository, follow the Subversion configuration instructions in the Bitnami wiki:

  • Stop the Subversion Server in the Bitnami Redmine Stack Manager Tool
  • Start the “Use Bitnami Redmine Stack” command prompt
  • Create a repository with the command
svnadmin create "D:\Bitnami-Redmine-data\subversion\repository"
  • Check your settings in “D:\Bitnami-Redmine-data\subversion\repository\conf\svnserve.conf”
  • Add users to “D:\Bitnami-Redmine-data\subversion\repository\conf\passwd” if you do not use SASL
  • Edit the file C:\Bitnami\redmine-3.3.0-1\subversion\scripts\serviceinstall.bat to add the repository root path using “–r param”:
    install redmineSubversion 
    -displayname "redmineSubversion" 
    -start auto "C:\Bitnami\redmine-3.3.0-1/subversion\bin\svnserve.exe" 
    -r "D:\Bitnami-Redmine-data\subversion\repository"

(note that this is a single command line)

  • Then re-install the SVN service from the Bitnami command prompt
Run serviceinstall.bat
Run serviceinstall.bat INSTALL
  • In the Bitnami Tool, start “Subversion Server”
  • Verify you are able to connect to the SVN repository using your favorite client.