XBMC

XBMC

Updated 10/23/2010: Based on some comments, I’ve released a new version with an installer and file for defining custom parameters. Big thanks to Joshka for showing me a neat registry trick that allowed me to create the installer. I’ve also moved the source to a subversion repository. Enjoy!

I recently took up the task of switching my media center software from Windows 7 Media Center to the Windows version of XBMC. I found XBMC easier to get working with obscure encodings of video files (it uses mplayer instead of the normal codec engine). But, my reasons for switching are not the point of this post. The point here is that switching to XBMC from Windows Media Center has a few challenges. One such challenge is getting the Windows Media Center remote to work in a nice way. Luckily, some excellent work has been done on that front. People have already provided premade media center remote configurations for XBMC. However, the “start” button on the media center remote still had the nasty habit of launching the Windows 7 Media Center app instead of launching XBMC.

I looked around the ol’ Internet for a solution to this problem. Turns out, the behavior of that “Start” or “Green” button on the media center remote is to cause a special key combination to be pressed. This key combination is bound to launching “C:\Windows\ehome\ehshell.exe.” The quickest workaround to the problem is to change ehshell.exe to something that launches XBMC. I then saw some people had written some batch files that launched XBMC. They then used a batch-to-exe converter to make it an executable and replaced ehshell.exe. That was great, but it still had a weakness. If, for some reason, XBMC was taken out of the foreground, it wouldn’t come back. Bummer. So I fixed it!

I wrote a little application to launch XBMC. It does a few things. First, it will check if XBMC is already running. If it is, it will bring it to the foreground for you. If it isn’t running, it will launch it. It will first try using the install location in the registry to find where to launch XBMC from. If it can’t find that, it will try the default location of the XBMC.exe file (both 32-bit and 64-bit versions).

Download The Installer

Manual Install Files and Instructions

Finally, here is the (very simple) source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace XbmcLauncher
{
    static class Program
    {
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);

        private const int SW_SHOWMAXIMIZED = 3;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            // Attempt to bring an existing XBMC to the foreground.
            // If none exists, open XBMC.
            if(!BringProcessToForeground())
                OpenXbmc();              
        }

        private static bool BringProcessToForeground()
        {
            Process[] processes = Process.GetProcessesByName("XBMC");
            if (processes.Length != 0)
            {
                // If XBMC is currently running, bring it to the foreground
                IntPtr hWnd = processes[0].MainWindowHandle;
                ShowWindow(hWnd, SW_SHOWMAXIMIZED);
                SetForegroundWindow(hWnd);
                return true;
            }
            return false;
        }

        private static void OpenXbmc()
        {
            string xbmcPath = null;

            // Attempt to find the XBMC executable location via the registry
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\XBMC");

            if (key != null) // If the path is in the registry use it to open XBMC
            {
                xbmcPath = key.GetValue("") as string;
                if (LaunchXbmcProcess(xbmcPath + @"\XBMC.exe"))
                    return;
            }
            else // Otherwise, we'll try to use the default locations
            {
                string x86Path = @"C:\Program Files\XBMC\XBMC.exe";
                string x64Path = @"C:\Program Files (x86)\XBMC\XBMC.exe";

                if (LaunchXbmcProcess(x86Path))
                    return;
                else
                    LaunchXbmcProcess(x64Path);
            }          
        }

        private static bool LaunchXbmcProcess(string path)
        {
            if (path != null && File.Exists(path))
            {
                string args = "";
                Process proc = new Process();

                if(File.Exists("XBMCLaunchArgs.txt"))
                {
                    using (StreamReader argStream = File.OpenText("XBMCLaunchArgs.txt"))
                    {
                        args = argStream.ReadLine();
                        argStream.Close();
                    }
                }
                       
                proc.StartInfo = new ProcessStartInfo(path, args);
                proc.Start();
                BringProcessToForeground();
                return true;
            }
            return false;
        }
    }
}

Get the full source, project files, and install scripts at https://www.inchoatethoughts.com/xbmclauncher/ (subversion)