Accessing Windows API from Ruby – Using Win32API library

Ruby is used extensively in Web applications thanks to Ruby on Rails. But you can also develop Windows applications using Ruby. Interestingly the Windows API support is part of the standard installation (only on Microsoft Windows installations) and it is quite easy to use it!

In order to use Windows API, you need to import “Win32API” library in your applications.
You can then use the Win32API class to create a reference to an API method and can call it. The following sample program shows how this can be done. This application will display a native Windows message box,


require "Win32API"

message = "This is a sample Windows message box generated using Win32API"
title = "Win32API from Ruby"

api ='user32', 'MessageBox',['L', 'P', 'P', 'L'],'I'),message,title,0)

When you run the above program, you will get a message box similar to the following one,

Now let us analyze our sample program in depth. The first line imports the standard Win32API library. Then we create two variables (message and title) which will hold the message to be displayed and the title of the message box.

Now using, we are creating a new instance of a Windows API method. The first parameter (user32) indicates the DLL which contains the API method. In this case the DLL is user32.dll. The second parameter is the name of the API method (MessageBox). The third parameter is an array indicating the type of all the parameters passed to API method (MessageBox). In the array, L stands for long number and P stands for pointer to string (string variable). The last parameter indicates the return type. In this case I stands for Integer.

Now using call method on the API reference we invoke MessageBox method. Note that the type of parameters matches the third array parameter in the constructor. First parameter is the id of the parent windows (in this case there is no parent and hence 0) and the last parameter indicates the type of message box (0 indicates default message box).

Following is another sample ruby program which uses Windows API to print out the logged in user name and also the computer name,

require "Win32API"

# Returns the computer name
def getComputerName
  name = " " * 128
  size = "128"'kernel32','GetComputerName', ['P','P'],'I').call(name,size)
  return name.unpack("A*")

# Returns current logged in Windows user name
def getUserName
  name = " " * 128
  size = "128"'advapi32','GetUserName', ['P','P'],'I').call(name,size)
  return name.unpack("A*")

puts "Computer Name: #{getComputerName}"
puts "User Name: #{getUserName}"

In the above sample, note that the second parameter is a pointer to the size of the first parameter. In Ruby there are no pointers and hence the size needs to be passed as a string value. Also we need to use unpack method to remove the trailing null character returned by API call.

Check out the following API definition for GetUserName (from MSDN),

  __out    LPTSTR lpBuffer,
  __inout  LPDWORD lpnSize

A pointer to the buffer to receive the user’s logon name. If this buffer is not large enough to contain the entire user name, the function fails. A buffer size of (UNLEN + 1) characters will hold the maximum length user name including the terminating null character. UNLEN is defined in Lmcons.h.

On input, this variable specifies the size of the lpBuffer buffer, in TCHARs. On output, the variable receives the number of TCHARs copied to the buffer, including the terminating null character.

As you can guess, the parameter passing and parsing return values from API quickly becomes tedious. So from a productivity angle using Windows API to build full fledged Windows applications is not recommended.

2 Responses to “Accessing Windows API from Ruby – Using Win32API library”

  1. Why can’t I send more than 16 params in the method?

  2. Above function’s return statements should be converted from
    return name.unpack(“A*”)
    return name.unpack(“A*”)[0]
    if you plan to use it along with strings. Otherwise
    mystring = “Your username is “+getUserName+”, and you’re on computer called “+getComputerName
    puts mystring
    will result in
    Your username is [“UserName”], and you’re on computer called [“ComputerName”]

    At least that is in my case.

Leave a Reply