我正在尝试创建一个用于Windows服务的私人消息队列。我在我的服务ProjectInstaller
课程中创建了队列。在所述类的构造函数中,我创建了一个MessageQueueInstaller
对象,并将其添加到我的本地Installer.Installers
属性中,如下所示:
var path = _config?.Settings[QUEUE_PATH]?.Value;
if (string.IsNullOrEmpty(path))
{
Console.WriteLine($"Could not install MSMQ message queue. Cannot install service. Missing private queue path value.");
throw new ArgumentNullException(QUEUE_PATH, "Cannot create private message queue with null queue path.");
}
_q = new MessageQueueInstaller();
_q.Label = "Queue Name";
_q.Path = path;
_q.Transactional = true;
Installers.Add(_q);
由于我希望在安装服务时传入凭据,并且我希望运行该服务的帐户能够完全访问正在创建的消息队列,因此我订阅了AfterInstall
我的ServiceProcessInstaller
的事件,以便像这样获取用户名:
_serviceProcessInstaller.AfterInstall += (sender, args) =>
{
_q.Permissions = new AccessControlList()
{
new AccessControlEntry(new Trustee(_serviceProcessInstaller.Username, null, TrusteeType.User),
GenericAccessRights.All, StandardAccessRights.All, AccessControlEntryType.Allow)
};
};
此过程成功完成,并且ACL条目将添加到我的专用队列的安全选项卡中,并带有预期值,但是,当运行需要与MSMQ交互的服务时,我收到以下错误:
拒绝访问消息队列系统
奇怪的是,如果我从队列的安全选项卡中手动创建完全相同的ACL条目,一切都神奇地起作用了!
另外,如果我以编程方式创建所有ACL(最后是上面的错误),那么然后设置' Everyone'手动完全控制,它也有效,但设置'每个人''在我们设置实际帐户不的同一过程中完全控制。
最后,我在NT AUTHORITY \ Network Service'下运行MSMQ服务。我还尝试以编程方式完全控制添加该帐户(看起来好像设置了所有权限,但仍然收到相同的错误),并且我还尝试将MSMQ服务作为本地系统运行没有用。
老实说,我不知道该怎么做。据我所知,权限是相同的,无论它们是以编程方式还是手动方式添加,但显然实际上并非如此,否则这将起作用。
我在这里错过了什么?
如果需要其他背景信息,请与我们联系。谢谢!
答案 0 :(得分:1)
我们使用以下代码创建MSMQ队列并设置权限。它运作良好:
public void CreateQueueIfNotExists(string queueName, List<string> users)
{
if (!MessageQueue.Exists(queueName))
{
MessageQueue.Create(queueName);
var queue = new MessageQueue(queueName);
//set permissions for those users
foreach (var user in users)
{
queue.SetPermissions(user, MessageQueueAccessRights.ReceiveMessage | MessageQueueAccessRights.WriteMessage, AccessControlEntryType.Allow);
}
}
}