tags:

views:

97

answers:

2

I have a gem, roundhouse, which is an application compiled with .NET (C#). Runs on Windows and it should run in a 32 bit process.

To set up my gemspec, I set:

 Gem::Specification.new do |s|
  s.platform = 'mswin32'
  s.name        = 'roundhouse'
  s.version     = version
  s.files = Dir['lib/**/*'] + Dir['bin/**/*']
  s.bindir = 'bin'
  s.executables << 'rh.exe'

When I install the gem, I should be able to type rh.exe from the command line at any path and it should run correctly.

In practice, I'm not seeing this work correctly. This is what I'm getting back:

Window has this for the header: 16 bit MS-DOS Subsystem

C:\WINDOWS\system32\cmd.exe - rh.exe

The NTVDM CPU has encountered an illegal instruction.

CS:xxxx IP:xxxx OP:xx xx xx xx xx Choose 'Close' to terminate the application.

Here is a picture of the issue (link to TwitPic): Error

If I go to the directory where the item was installed, I can run it and it works great. It's just something in the registration of the command to run from anywhere.

I did quite a bit of searching before asking and came up with nothing. It could be that I don't know what I should be searching for. So let me ask the question, is there a way to register an executable with gems for windows executable applications (built with .NET) and have them register properly with the command line? If so, how is that done?

UPDATE: I found that gems creates a shim in the C:\Ruby\bin directory that points back to the other file. So there is a rh.exe file that is really just a text file. This is its contents:

#!C:/Ruby/bin/ruby.exe
#
# This file was generated by RubyGems.
#
# The application 'roundhouse' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
  version = $1
  ARGV.shift
end

gem 'roundhouse', version
load Gem.bin_path('roundhouse', 'rh.exe', version)
+2  A: 

if you're distributing it with the file "rh.exe" then you'll want to create a file

bin/rh

s.executables << 'bin/rh'

then when it's installed gems will create an "rh.bat" file which runs ruby "bin/rh" essentially (as you've seen).

So within bin/rh put something like

result = system(File.dirname(__FILE__) + "/rh.exe" ARGV.join(' '))
exit 1 unless result
rogerdpack
This is definitely a step in the right direction. It's not passing the arguments correctly...yet.You missed a + between rh.exe and ARGV, but it's definitely a good step.
ferventcoder
dru added a space in there as well, which was needed. For some reason I looked at that last night and thought it was already doing that. :D
ferventcoder
I can't split answers, but you both answered the question. Dru just elaborated further.
ferventcoder
in reality you should put quotes around the arguments, too, this was just an example. The real question is "if this is an executable, is distributing it via rubygems the thing that is best?"
rogerdpack
+1  A: 
result = system(File.dirname(__FILE__) + "/rh.exe " + ARGV.join(' '))
exit 1 unless result

So the endresult should maybe look like? note the space after 'rh.exe'

drusellers
Rock on! I can't split answers.
ferventcoder