Jon Thysell

Xbox engineer. Fiction writer. Returned Peace Corps Volunteer. Ukulele nut. Nerd.

Using a batch file to launch Gtk# apps on Windows with Mono instead of .NET

Mono is great for cross-platform development – maybe not so great for cross-platform deployment. In working on Chordious, a Gtk# app written entirely in MonoDevelop on an Ubuntu machine, there’s been no greater struggle than trying to find a simple “double-click” launch of Chordious on Windows.

Yes, if you stick with just the “standard” libraries and write your GUI with Windows.Forms, all an end-user has to do is double-click on your executable, and let .NET run it. But what if you don’t want that? What if your app needs to be launched by the Mono Runtime?

Realistically, the bigger hurdle is getting your end-users to install Mono in the first place – but even if you can get them past that – you’ll still need a double-click way to start your app. You’ll never convince them to start up a Mono command prompt and manually launch your app with mono.exe. And unfortunately for us, the Mono installer for Windows isn’t so nice as to add itself to the PATH, so you can’t just get away with a one-line batch file.

Enter StartMonoApp.cmd:

@echo off
setlocal

rem Script: StartMonoApp.cmd
rem Author: Jon Thysell <thysell@gmail.com>
rem Date: 7/15/2014

set _MonoApp=YourMonoApp.exe

rem Checking for 32/64bit machine

if exist "%SYSTEMROOT%\SysWOW64" (
    set WOW6432=\Wow6432Node
) else (
    set WOW6432=
)

rem Find default Mono version

set _MonoBase=HKEY_LOCAL_MACHINE\SOFTWARE%WOW6432%\Novell\Mono

echo Looking for Mono registry key %_MonoBase%

for /f "Tokens=2*" %%I in ('reg query "%_MonoBase%" /V "DefaultCLR" 2^>nul') do set _MonoVersion=%%J

if "%_MonoVersion%" equ "" (
    echo ERROR: DefaultCLR not found!
    goto nomono
)

echo Default Mono is %_MonoVersion%

rem Find the path to where that version of Mono is installed

for /f "Tokens=2*" %%I in ('reg query "%_MonoBase%\%_MonoVersion%" /V "SdkInstallRoot" 2^>nul') do set _MonoPath=%%J

if "%_MonoPath" neq "" (
    if not exist "%_MonoPath%" (
        echo ERROR: SdkInstallRoot not found!
        goto nomono
    )
)

echo Mono %_MonoVersion% installed at %_MonoPath%

rem Check for the mono.exe binary

if not exist "%_MonoPath%\bin\mono.exe" (
    echo ERROR: mono.exe not found!
    goto nomono
)

set PATH=%_MonoPath%\bin;%PATH%

rem Launch the app

pushd %~dp0

echo Launching %_MonoApp%

start mono.exe %_MonoApp% %*

popd

goto :quit

:nomono
echo ERROR: Unable to find Mono. Please install Mono and try again.
pause

:quit
endlocal

So let’s say you’ve got yourself a nice little Gtk# app named GreatMonoApp.exe. To make a double-click launcher that uses Mono, simply:

  1. Copy the contents (minus the line numbers) of the script above into Notepad.
  2. Update line 8 with the name of your executable (in this example, the line should read set _MonoApp=GreatMonoApp.exe).
  3. Save the file into the same directory as your executable. (You can name the file whatever you want, just make sure you save it as a .cmd, not .txt, file).

There you go! Double-click on that new batch file and your app should launch via Mono. You might see a flicker or two of command prompts, but otherwise works quite well. If something does go wrong, the command prompt will stay open with an (hopefully useful) error message for you to debug.

How does the script work? Essentially it looks for the registry keys that the Mono for Windows installer created, and uses them to find where the mono.exe binary is. Then it adds that folder to your PATH (temporarily) so it can use mono.exe to launch your app. And as mentioned before, if there’s anything wrong (can’t find the registry keys, can’t find the folder or binaries) the script will show an error.

I hope someone out there finds this as useful as I do – I’ve spent forever trying to solve this problem, with progressively more and more complicated scripts. I’ve verified that the script works on Windows XP, 7, 8, and 8.1, 32 and 64-bit.

Happy coding!

/jon

P.S. I have no reason to believe the script won’t work on Vista, I just don’t have access to a Vista machine to test it. Sorry true believers.

Chordious 0.8.0 available, less requirements on Windows installs

I’ve had the code for Chordious 0.8.0 sitting on my laptop for a couple months now – haven’t found the time to add anything more to the pre-1.0 line since I plan on re-factoring a lot of the app after 1.0. Nothing too fancy in this release then:

  • Chord finder: Added the option to produce mirrored diagrams (for “left-handed” chords)
  • Windows: Removed the dependency on GTK# for .NET (now you just need Mono)
  • Windows: Fixed the StartChordious.cmd script to work on Win XP
  • Bug fix: Selected chords in the Chord Finder now unselect between searches

Check out these lovely screenshots (of 0.6.0):

For download links, check out my Chordious page, or the Chordious project page at Launchpad. You’ll find links for both the binaries and the source. Be sure to download the right binaries for your system (Windows or Linux / Mac OS X), and follow the installation instructions carefully.

Happy strumming!

/jon

Note: Chordious is still beta software, so please be sure to backup any ChordDocuments and diagrams you create. If you run into issues, or have feature requests, let me know!

Building the Picade Mini Part V, final touches

In Part I I put together the cabinet, in Part II I got the main electronics installed, in Part III I created a custom rear jack panel, and in Part IV I got everything up and running 95% how I wanted.

After that last post, I took the machine to work to show off. Got lots of people to try it out, and the biggest bit of feedback was people wanted their MAME games. I also really wanted to play six-button Sega Genesis games. So I spent some time updating my secondary RetroPie build to the latest version, which gave me a much more functional Genesis emulator, including save state support and six-button controls. Then I switched to mame4all-pi, and put the correct MAME roms on the box, which finally gave me working MAME games.

Once I was sure the update would improve things without breaking my Picade, I went ahead and switched back to that build. I updated the Picade, and when that was done, it turns out I was using the wrong resolution before. The Picade Mini has a 4:3 screen, and I was outputting widescreen before. Once I fixed that, I changed the splashscreen to use the official Picade art from the Kickstarter.

The last bit of work was getting MAME working. It involved making all of the requisite folders mame4all-pi needs to save configs and high scores. Once that was done, I spent the time to go into MAME and reconfigure all of the controls to use what I have on my joystick. Everything I’ve done is in the updated configs file I’ve attached at the bottom of this post.

Here’s an updated video of the build in action:

And the original video if you missed it:

Enjoy!

/jon

My Picade Configs [184k ZIP] Updated 02-JUL-2014

I’ve configured my build to use as much screen real estate as possible without compromising on aspect ratios. The buttons are set up such 1-6 on the top map to playing buttons (Y X L B A R), the front are for Start and Select, and the side buttons are Escape and Control. Holding the right side button while I hit another button performs various emulator commands:

  • Left side – exit the emulator and return to the menu
  • B (bottom row, first button) – lower volume
  • A (bottom row, 2nd button) – raise volume
  • R (bottom row, last button) – hits Ctrl+C to forcefully exit any game
  • Y (top row, first button) – load state
  • X (top row, 2nd button) – save state
  • Select – bring up emulator menu

Includes configs for all of the RetroArch emulators, and for mame4all-pi. Feel free to change the configs to support your own needs.

Ten Years without Uncle Teeny

Uncle TeenyDear Uncle Teeny,

I still miss you.

If I can’t say anything else, I just need to get that out first. The writer in me wants to be eloquent, to pick and choose and dance around my words, and maybe halfway into this letter I’ll be able to do that, but until then I just needed to say that first.

Teeny's ObituarySo much has happened in the past ten years, I don’t know where to start. You were there when I moved into the dorms; I wish you could have been there when I graduated. I wish you could have seen me off to the Peace Corps, and been at the airport the day I came back.

When I moved to Washington, I wanted to share the news with you- again when I found Anne, again when I joined Xbox, again and again for every major event in my life.

When I asked Anne to marry me, when she said yes, I wanted to call and tell you.

You were missed at every holiday, every family event. I wish you could have seen Nickolis get married, could meet your grand nephews, could see him now, a young man following in your footsteps or service and public safety. I wish you could see Rachelle grow into a smart, strong, fun young woman.

Uncle Teeny (Young)You touched enough lives to fill a stadium- gave your ear, your shoulder, and the shirt off your back if needed. You helped others stay on the right track, and set an example to all who met you. If I become half the man you were, I’ll be satisfied I’ve done things right.

It’s been a hard ten years without you Uncle Teeny. We all still miss you very much.

Love,

Kamalani

In memory of Nick “Teeny” Jones, III
July 19, 1964 — March 11, 2004

Building the Picade Mini Part IV, let’s finish this up!

In Part I of this build, I put together the main parts of the cabinet. In Part II I got the main kit’s electronics installed and tested. In Part III I created a custom rear jack panel.

Next step was to finally install the rear door. The included hinges and latch worked perfectly.

Rear panel attached Rear panel open

With the rear door in place, it was time to install the Raspberry Pi and put into effect my grand wiring scheme.

The goal has always been a single power supply with a single power switch to get me into a ready to play system. With that in mind I installed a single throw, double pole switch.

The first pole is responsible for powering the monitor and customized USB hub directly. For the monitor I used the cut off the barrel-end of the included power supply. For the USB hub I severed the power leads for the host plug (so that it would never draw power from the Raspberry PI itself) and ran new power lines straight out the side. Simple enough, and both devices power up as soon as I hit the switch.

Rear panel wired 2Now for the Raspberry Pi itself, I need something else. If I run power straight from the switch to the Pi, then killing the power threatens corrupting the Pi’s SD card and killing the machine.

Since it’s a common enough problem, and since I didn’t want to reinvent the wheel, I simply used a Mausberry shutdown circuit. In concert with a small script that runs on the Pi itself, what the shutdown circuit does is uses a pair of GPIO pins on the Pi to monitor when the Pi is running. When the switch is thrown, the circuit tells the script to tell the Pi to perform a clean shutdown. After the shutdown occurs (killing the script), the circuit finally cuts power to the Pi.

So essentially I wire power straight from my jack to the shutdown circuit, and attach the second pole of my switch to the designated spots on the shutdown circuit. (There’s also room for an emergency swtich to reset the Mausberry circuit itself, but I didn’t bother).

Rear panel wired 1Sum total is that when the power switch is turned on, everything is powered on. When the switch is turned off, power is cut immediately to the monitor and USB hub, and a signal is sent to the Pi to shutdown cleanly. About 2-3 seconds later, the Pi shuts down and power is cut to the Pi.

So as long as I don’t physically pull out the jack, I can safely hit the power switch to power off the machine, even in the middle of a game, as long as I wait for a few seconds before pulling the actual plug. The speakers pop when the Pi loses power, so I know I’m safe to unplug.

The last bit of hardware setup was to connect the Pi in to everything. I connected the shutdown circuit and Ethernet jack to the Pi and both the rear USB jacks and the Picade controller to the USB hub (I’ll explain why later). I connected the HDMI from the monitor to the PI and the audio out from the Pi to the Picade board.

Finally, time to start playing with the software!

My first attempt at building an emulator rig with Raspberry Pi used the wonderful RetroPie Project. Since I had already gotten that up and running on another build, (with lots of games working) I decided to take a shortcut and clone that SD card as my starting point for my Picade.

First I tweaked the config.txt to optimize the display for the Mini’s screen (I’ll attach my config at the end of the post). Then I configured the Picade joystick as the new (and only) device. Again, I ended up needing to reprogram the Picade controller, as the default key selections, while great for MAME, actually caused all kinds of problems with RetroArch, which is the framework a lot of my emulators were using. (Again, I’ll add my configs to the end of the post).

The last real configuration (and it still needs some work) was for audio. By default, if you have HDMI connected, the Pi won’t output audio from the 3.5mm jack. I fixed that with the Raspberry Pi sound troubleshooting guide. (Hint, it’s amixer -c 0 cset numid=3 1).

The only audio hiccup I still have is that by default the sound is at max volume at boot. And it is LOUD. Even worse, it seems like potentially something is shorting on the Picade board- such that if the Picade board is wired directly to the Pi, and a loud sound plays, the controls straight up die. The solution I found for the controls was to connect the Picade controller board to the USB hub instead. As for the loud sound, my current workaround is to go in and out of the settings for Emulation Station (the front-end UI for the emulators) after boot. For some reason this resets the audio to regular ranges until I reset or power down.

After figuring that out, the box pretty much runs the way I want it to. I can play NES, SNES, GB, GBC, and GBA without any problems. Master System doesn’t work too well. Genesis works but the emulator (Picodrive) for some reason is locked to 3 button mode only. I haven’t gotten MAME to work yet- none of my roms are the right version it seems.

At this point the project is basically done. I might add a headphones jack, but the joystick itself is super loud anyway. The whole thing fits comfortably on my lap to play, but the front edge is sharp on the wrists so I might grind that down a bit.

Anyway, hope you enjoyed following my build!

/jon

My Picade Configs [184k ZIP] Updated 02-JUL-2014

I’ve configured my build to use as much screen real estate as possible without compromising on aspect ratios. The buttons are set up such 1-6 on the top map to playing buttons (Y X L B A R), the front are for Start and Select, and the side buttons are Escape and Control. Holding the right side button while I hit another button performs various emulator commands:

  • Left side – exit the emulator and return to the menu
  • B (bottom row, first button) – lower volume
  • A (bottom row, 2nd button) – raise volume
  • R (bottom row, last button) – hits Ctrl+C to forcefully exit any game
  • Y (top row, first button) – load state
  • X (top row, 2nd button) – save state
  • Select – bring up emulator menu

Feel free to change the configs to support your own needs.

Update: See the video: Picade Mini build running RetroPie.

Update: Part V is up.

Follow

Get every new post delivered to your Inbox.

Join 475 other followers