One approach we've used successfully is Named Pipes. In .net 3.5 they added native support so you don't have to use p/invoke to get at the appropriate win32 APIs.
Check out: http://www.switchonthecode.com/tutorials/dotnet-35-adds-named-pipes-support as an example.
In short, what you'll be doing is creating a client/server mechanism (the "named pipe") which has a specified name; the server will set up the pipe and await client connections...the client will connect to the pipe and send data across it.
The nice thing about this is you can send entire data structures easily (provided they're marked [Serializable]). This allows you to implement particular messages richly (and this includes Enums, too)
One thing to note: by default named pipes are synchronous (blocking) so your call to Connect() will run ~forever if the server is not up. You can either use the asynchronous mode or run your synchronous code in a Thread which you can later abandon/abort. Just keep that in mind when laying the groundwork as the switch to asynchronous pipe usage may be a bit of work if you haven't planned for it.
[Serializable]
public enum CmdType
{
cmdTypeOne,
someOtherCmdType
}
[Serializable]
public class Command
{
CmdType eCmdType;
// other command payload
}