(Part 2 of a 4-part series of tips and tricks for installers for win32 services in .NET.)
While I'm on the topic of doing stuff while installing, it's also nice and
easy to create and configure a Message Queue in a ServiceInstaller life cycle
event.
MessageQueue.Create is a nice static method that takes the queue path and
optionally a boolean to indicate transactional or non-transactional. Of course,
you'll want to do MessageQueue.Exists first to make sure you're not trying to
create anything you already have.
Unfortunately, it won't take WCF path syntax, nor is there any way I've yet
seen to automatically convert between the oldschool MSMQ path snytax and the WCF
style, so at least for the time being there are two separate properties in
Settings that both have to be updated if the queue's path changes. It's not
ideal, so I might look at it again later. For refrence's sake, here are the two
examples:
Raw Path: .\Private$\ExampleQueue
WCF Path: net.msmq://localhost/private/ExampleQueue
One annoying thing when you create a Message Queue is that by default,
only the queue owner (which will probably be System if
you're creating it from installer code) gets any rights to receive or peek
messages from the queue. That's all well and good if your service happens to be
running as System, but if another user makes more sense for your application,
that's no good to you. Fortunately, it's easy to change! If you assign it,
MessageQueue.Create returns an instance of a MessageQueue object representing
the just-created queue. The instance method SetPermissions just takes as
parameters a string representation of a user, and a MessageQueueAccessRights
enum representing the access rights to append to the default list.
So our completed code looks like this:
private void
serviceInstaller1_BeforeInstall(object sender, InstallEventArgs e)
{
if (!MessageQueue.Exists(Settings.Default.RawMSMQPath))
{
using (MessageQueue queue = MessageQueue.Create(Settings.Default.RawMSMQPath,
true))
{
queue.SetPermissions("NETWORK SERVICE",
MessageQueueAccessRights.FullControl);
}
}
}
Of course, this is only good if MSMQ is actually an installed component on
the host OS, which it isn't by default. In my next post, I'll go over how to
set up a check for Message Queuing as a launch condition in your setup project's
MSI and abort the install if it isn't present.