**Microsoft Message Queuing**或**MSMQ**微软公司实现的一种消息队列，始于Windows NT 4与Windows 95。Windows Server 2016与Windows 10仍然包含这种组件。1999年起，Microsoft Embedded平台以及Windows CE 3.0也开始支持这一组件。

简介
--

MSMQ作为一种消息协议，允许多服务器/多进程通信，即使不总是保持互联。而sockets与其他网络协议要求直连总是成立。 

MSMQ从1997年开始可用。

MSMQ是可靠分发消息。分发失败的消息保存在队列中直到目标可达时重发该消息。还支持安全与优先级的消息机制。可以创建死信队列（英语：）用于调试。

MSMQ支持可持续性与不可持续性消息，使得性能与消息是否写到磁盘的一致性上可以权衡。不可持续性消息只能用于向非事务性队列发送快速消息。 

MSMQ支持事务处理。允许多个动作发给多个队列中包装为单个事务。微软分布式事务协调器 (MSDTC) 支持对MSMQ或其他资源的事务访问。 

MSMQ使用下述端口:

* TCP: 1801
* RPC: 135, 2101\*, 2103\*, 2105\*
* UDP: 3527, 1801
* 这些端口可能增加11，如果RPC端口的初始选择被使用。端口135用于查询2xxx端口。

版本历史
----

* Version 1.0 (1997年5月). 支持Windows 95, Windows NT 4.0 SP3, Windows 98 与 Windows Me.
* Version 2.0, 包含在Windows 2000中.
	+ 新特性包括: Support for registering public message queues in Active Directory, 128-bit encryption and digital certificate support, full COM support for message properties (achieving functional parity with the Win32 API function calls, full DNS path name support, improved performance in multi-threaded applications.
* Version 3.0, 包含在Windows XP (专业版, 非家庭版) 与 Windows Server 2003.
	+ 新特性包括: Internet Messaging (referencing queues via HTTP, SOAP-formatted messages, MSMQ support for Internet Information Services), queue aliases, multicasting of messages, and additional support for programmatic maintenance and administration of queues and MSMQ itself.
* Version 4.0, 包含在Windows Vista与Windows Server 2008.
	+ 新特性包括: Subqueues, improved support for "poison messages" (messages which continually fail to be processed correctly by the receiver), and support for transactional receives of messages from a remote queue.
* Version 5.0, 包含在Windows 7 与 Windows Server 2008 R2.
	+ 新特性包括: support for Secure Hash Algorithm 2.0 (SHA2) and all advanced hash algorithms that are supported in Windows 2008 R2; by default, weaker hash algorithms are disabled.
* Version 6.0, 包含在Windows 8 与 Windows Server 2012.
* Version 6.3, 包含在 Windows 8.1 与 Windows Server 2012 R2.

使用
--

C#例子：

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
 public class QueueManger
 {
 /// <summary>
 /// 创建MSMQ队列
 /// </summary>
 /// <param name="queuePath">队列路径</param>
 /// <param name="transactional">是否事务队列</param>
 public static void Createqueue(string queuePath, bool transactional = false)
 {
 try
 {
 //判断队列是否存在
 if (!MessageQueue.Exists(queuePath))
 {
 MessageQueue.Create(queuePath);
 Console.WriteLine(queuePath + "已成功创建！");
 }
 else
 {
 Console.WriteLine(queuePath + "已经存在！");
 }
 }
 catch (MessageQueueException e)
 {
 Console.WriteLine(e.Message);
 }
 }
 /// <summary>
 /// 删除队列
 /// </summary>
 /// <param name="queuePath"></param>
 public static void Deletequeue(string queuePath)
 {
 try
 {
 //判断队列是否存在
 if (MessageQueue.Exists(queuePath))
 {
 MessageQueue.Delete(@".\private$\myQueue");
 Console.WriteLine(queuePath + "已删除！");
 }
 else
 {
 Console.WriteLine(queuePath + "不存在！");
 }
 }
 catch (MessageQueueException e)
 {
 Console.WriteLine(e.Message);
 }
 }
 /// <summary>
 /// 发送消息
 /// </summary>
 /// <typeparam name="T">用户数据类型</typeparam>
 /// <param name="target">用户数据</param>
 /// <param name="queuePath">队列名称</param>
 /// <param name="tran"></param>
 /// <returns></returns>
 public static bool SendMessage<T>(T target, string queuePath, MessageQueueTransaction tran = null)
 {
 try
 {
 //连接到本地的队列
 MessageQueue myQueue = new MessageQueue(queuePath);
 System.Messaging.Message myMessage = new System.Messaging.Message();
 myMessage.Body = target;
 myMessage.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
 //发送消息到队列中
 if (tran == null)
 {
 myQueue.Send(myMessage);
 }
 else
 {
 myQueue.Send(myMessage, tran);
 }
 Console.WriteLine("消息已成功发送到"+queuePath + "队列！");
 return true;
 }
 catch (ArgumentException e)
 {
 Console.WriteLine(e.Message);
 return false;
 }
 }
 /// <summary>
 /// 接收消息
 /// </summary>
 /// <typeparam name="T">用户的数据类型</typeparam>
 /// <param name="queuePath">消息路径</param>
 /// <returns>用户填充在消息当中的数据</returns>
 public static T ReceiveMessage<T>(string queuePath,MessageQueueTransaction tran=null)
 {
 //连接到本地队列
 MessageQueue myQueue = new MessageQueue(queuePath);
 myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
 try
 {
 //从队列中接收消息
 System.Messaging.Message myMessage = tran == null ? myQueue.Receive() : myQueue.Receive(tran);
 return (T)myMessage.Body; //获取消息的内容
 }
 catch (MessageQueueException e)
 {
 Console.WriteLine(e.Message);
 }
 catch (InvalidCastException e)
 {
 Console.WriteLine(e.Message);
 }
 return default(T);
 }
 /// <summary>
 /// 采用Peek方法接收消息
 /// </summary>
 /// <typeparam name="T">用户数据类型</typeparam>
 /// <param name="queuePath">队列路径</param>
 /// <returns>用户数据</returns>
 public static T ReceiveMessageByPeek<T>(string queuePath)
 {
 //连接到本地队列
 MessageQueue myQueue = new MessageQueue(queuePath);
 myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
 try
 {
 //从队列中接收消息
 System.Messaging.Message myMessage = myQueue.Peek();
 return (T)myMessage.Body; //获取消息的内容
 }
 catch (MessageQueueException e)
 {
 Console.WriteLine(e.Message);
 }
 catch (InvalidCastException e)
 {
 Console.WriteLine(e.Message);
 }
 return default(T);
 }
 /// <summary>
 /// 获取队列中的所有消息
 /// </summary>
 /// <typeparam name="T">用户数据类型</typeparam>
 /// <param name="queuePath">队列路径</param>
 /// <returns>用户数据集合</returns>
 public static List<T> GetAllMessage<T>(string queuePath)
 {
 MessageQueue myQueue = new MessageQueue(queuePath);
 myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(T) });
 try
 {
 Message[] msgArr= myQueue.GetAllMessages();
 List<T> list=new List<T>();
 msgArr.ToList().ForEach((o) => 
 {
 list.Add((T)o.Body);
 });
 return list;
 }
 catch(Exception e)
 {
 Console.WriteLine(e.Message);
 }
 return null;
 }
 }
}

namespace Test
{
 public class Student
 {
 /// <summary>
 /// 年龄
 /// </summary>
 public int Age { get; set; }
 /// <summary>
 /// 姓名
 /// </summary>
 public string Name { get; set; }
 }
}

namespace Test
{
 class Program
 {
 static void Main(string[] args)
 {
 string queuepath = @".\private$\myQueue";
 //QueueManger.Createqueue(queuepath);
 //Student stu = new Student() { Name="shaoshun",Age=18};
 //QueueManger.SendMessage<Student>(stu, queuepath);
 //Student stu= QueueManger.ReceiveMessageByPeek<Student>(queuepath);
 //Student stu = QueueManger.ReceiveMessage<Student>(queuepath);
 //Console.WriteLine(stu.Name);

 QueueManger.Deletequeue(queuepath);
 QueueManger.Createqueue(queuepath);
 MessageQueueTransaction tran = new MessageQueueTransaction();
 tran.Begin();
 try
 {
 Student stu;
 for (int i = 0; i < 4; i++)
 {
 stu=new Student(){Name="shaoshun"+i,Age=i};
 QueueManger.SendMessage<Student>(stu, queuepath, tran);
 if (i == 3)
 {
 throw new Exception();
 }
 }
 tran.Commit();
 }
 catch
 {
 tran.Abort();
 }
 Console.ReadKey();
 }
 }
}

```

C语言调用Windows API例子：

```
#include "windows.h" 
#include "mq.h" 
#include "tchar.h" 
#define BUFLEN = 256 ; 
 
HRESULT CreateMSMQQueue( 
 LPWSTR wszPathName, 
 PSECURITY\_DESCRIPTOR pSecurityDescriptor, 
 LPWSTR wszOutFormatName, 
 DWORD \*pdwOutFormatNameLength 
 ) 
{ 
 
 // Define the maximum number of queue properties. 
 const int NUMBEROFPROPERTIES = 2; 
 
 // Define a queue property structure and the structures needed to initialize it. 
 MQQUEUEPROPS QueueProps; 
 MQPROPVARIANT aQueuePropVar[NUMBEROFPROPERTIES]; 
 QUEUEPROPID aQueuePropId[NUMBEROFPROPERTIES]; 
 HRESULT aQueueStatus[NUMBEROFPROPERTIES]; 
 HRESULT hr = MQ\_OK; 
 
 // Validate the input parameters. 
 if (wszPathName == NULL || wszOutFormatName == NULL || pdwOutFormatNameLength == NULL) 
 { 
 return MQ\_ERROR\_INVALID\_PARAMETER; 
 } 
 
 // Set queue properties. 
 DWORD cPropId = 0; 
 aQueuePropId[cPropId] = PROPID\_Q\_PATHNAME; 
 aQueuePropVar[cPropId].vt = VT\_LPWSTR; 
 aQueuePropVar[cPropId].pwszVal = wszPathName; 
 cPropId++; 
 
 WCHAR wszLabel[MQ\_MAX\_Q\_LABEL\_LEN] = L"Test Queue"; 
 aQueuePropId[cPropId] = PROPID\_Q\_LABEL; 
 aQueuePropVar[cPropId].vt = VT\_LPWSTR; 
 aQueuePropVar[cPropId].pwszVal = wszLabel; 
 cPropId++; 
 
 // Initialize the MQQUEUEPROPS structure. 
 QueueProps.cProp = cPropId; // Number of properties 
 QueueProps.aPropID = aQueuePropId; // IDs of the queue properties 
 QueueProps.aPropVar = aQueuePropVar; // Values of the queue properties 
 QueueProps.aStatus = aQueueStatus; // Pointer to the return status 
 
 // Call MQCreateQueue to create the queue. 
 WCHAR wszFormatNameBuffer[BUFLEN]; 
 DWORD dwFormatNameBufferLength = BUFLEN; 
 hr = MQCreateQueue(pSecurityDescriptor, // Security descriptor 
 &QueueProps, // Address of queue property structure 
 wszFormatNameBuffer, // Pointer to format name buffer 
 &dwFormatNameBufferLength); // Pointer to receive the queue's format name length in Unicode characters not bytes. 
 
 // Return the format name if the queue is created successfully. 
 if (hr == MQ\_OK || hr == MQ\_INFORMATION\_PROPERTY) 
 { 
 if (\*pdwOutFormatNameLength >= dwFormatNameBufferLength) 
 { 
 wcsncpy\_s(wszOutFormatName, \*pdwOutFormatNameLength - 1, wszFormatNameBuffer, \_TRUNCATE); 
 // \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 
 // You must copy wszFormatNameBuffer into the 
 // wszOutFormatName buffer. 
 // \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 
 wszOutFormatName[\*pdwOutFormatNameLength - 1] = L'\0'; 
 \*pdwOutFormatNameLength = dwFormatNameBufferLength; 
 } 
 else 
 { 
 wprintf(L"The queue was created, but its format name cannot be returned.\n"); 
 } 
 } 
 return hr; 
}

```

参见
--

参考文献
----

1. ↑ . Microsoft Developer Network.  [2009-11-25]. （原始内容存档于2018-10-11）.
2. ↑  InformationWeek News Connects The Business Technology Community. Informationweek.com (2014-02-04). Retrieved on 2014-02-22. （页面存档备份，存于）
3. ↑  TCP ports, UDP ports, and RPC ports that are used by Message Queuing （页面存档备份，存于）. Support.microsoft.com (2011-09-28). Retrieved on 2014-02-22.
4. ↑  
. Message Queuing (MSMQ). Microsoft Developer Network.  [2006-08-05]. [永久]
5. ↑ . Message Queuing (MSMQ). Microsoft Developer Network.  [2006-08-05]. （原始内容存档于2007-12-24）.
6. ↑ . Message Queuing (MSMQ). Microsoft Developer Network.  [2006-08-05]. （原始内容存档于2007-02-12）.
7. ↑ .  [2018-10-11]. （原始内容存档于2008-01-30）.
8. ↑ . Message Queuing (MSMQ). Microsoft TechNet.  [2006-08-05]. （原始内容存档于2017-08-26）.

外部链接
----

* MSDN documentation （页面存档备份，存于）

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
Microsoft Windows组件 |
| --- |
|  |
| 管理工具 | 
* 命令提示字元
* + 元件列表
* 裝置管理員
* 磁碟清理
* 磁碟重組工具
* 驅動程式檢查器
* 事件檢視器
* IExpress
* 管理控制台
* Netsh
* 修復主控台
* 資源監視器
* 性能监视器
* 設定
* Sysprep
* 系統設定
* 系統文件檢查器
* 系統策略编辑器
* 系統還原
* 任务管理器
* Windows輕鬆傳輸
* Windows錯誤報告
* Windows Installer
* Windows PowerShell
* Windows Update
* WinPE
* WinRE
* WMI

 |
|  |
| 應用程式 | 
* 3D 檢視器
* 
* 小算盤
* 字元對應表
* Cortana
* DVD播放器
* Edge
* 傳真和掃描
* 
* 取得協助（英语：）
* Groove
* Internet Explorer
* 放大鏡
* 郵件
* 地圖
* Media Player
* MSN應用（新聞，天氣，體育，財經）
* 電影與電視
* 行動中心
* 朗讀程式
* 記事本
* 
* OneDrive
* OneNote
* 小畫家 3D
* 小畫家
* 
* 照片
* 遠端協助（英语：）
* 剪取工具
* 語音辨識
* 
* 
* 提示（英语：）
* 錄音機
* Windows Ink
* WordPad
* Xbox
* XPS查看器
* 

 |
|  |
| Shell | 
* 重要訊息中心
* Aero
* 自動播放
* 自動執行
* ClearType
* 檔案總管
* 搜尋
	+ 索引服务
	+ IFilter
	+ 儲存的搜尋
	+ 命名空間
	+ 特殊文件夹
* 開始功能表
* 工作列
* 任务视图
* Windows XP主題

 |
|  |
| 服務 | 
* 服务控制管理器
* 后台智能传输服务
* 通用日志文件系统
* 多媒體類別排程器（英语：）
* 磁碟區陰影複製服務
* 工作排程器
* 錯誤報告
* 無線零配置
* 推送通知服務

 |
|  |
| 文件系統 | 
* CDFS
* DFS
* exFAT
* 可安装文件系统
* FAT
* NTFS
	+ 硬链接
	+ 連接點
	+ 挂载点
	+ 重解析点
	+ 符號連結
	+ TxF（英语：）
	+ EFS
* ReFS
* UDF
* WinFS

 |
|  |
| 伺服器 | 
* 網域（英语：）
* Active Directory
* DNS（英语：）
* 组策略
* 漫游用户配置文件
* 資料夾重新導向（英语：）
* 分散式交易協調器
* MSMQ
* Windows Media服務
* 活动目录权限管理服务（英语：）
* IIS
* 遠端桌面服務
* WSUS
* SharePoint
* 網路存取保護
* PWS
* 文件复制服务（英语：）
* 遠端差異壓縮（英语：）
* 適用於UNIX的列印服務（英语：）
* Windows部署服務（英语：）
* 系統資源管理員（英语：）
* Hyper-V
* 伺服器核心

 |
|  |
| 架構 | 
* Windows NT的架構
* 啟動處理程序（英语：）
* csrss.exe
* 桌面視窗管理員
* 可攜式格式
	+ EXE
	+ DLL
* 增强写入筛选器（英语：）
* 圖形裝置介面
* hal.dll
* I/O请求数据包
* 程式庫檔
* 核心交易管理員
* 庫
* 邏輯磁碟管理
* lsass
* MinWin（英语：）
* NTLDR
* Windows開機管理程式
* ntoskrnl.exe
* 物件管理
* Open XML紙張規範
* 注册表
* Windows资源保护
* 安全性帳戶管理員（英语：）
* 伺服器訊息區
* 磁碟區陰影複製服務
* SMSS
* 系统空闲进程
* 使用者（英语：）
* WHEA（英语：）
* Win32主控台
* Winlogon
* 华生医生（英语：）

 |
|  |
| 安全性 | 
* 安全性與維護
* BitLocker
* 資料執行防止
* 家長監護服務
* 內核修補程式保護
* 認證相符控制
* 受保护媒体路径
* 使用者帳戶控制
* 控制台元件列表
* Windows Defender
* Windows防火牆

 |
|  |
| 兼容性 | 
* COMMAND.COM
* DOS虚拟机（英语：）
* Windows on Windows
* WoW64
* 适用于 Linux 的 Windows 子系统

 |
|  |
| API | 
* 動態指令碼處理（英语：）
	+ WSH
	+ VBScript
	+ JScript
* COM
	+ ActiveX
	+ ActiveX文档（英语：）
	+ COM结构化存储
	+ DCOM
	+ OLE
	+ OLE自动化（英语：）
	+ Transaction Server
* DirectX
* .NET Framework
* Windows Holographic
* Windows Runtime
* 通用Windows平台（UWP）

 |
|  |
| 已經终止 | 

|  |  |
| --- | --- |
| 遊戲 | 
* 3D Pinball
* Chess Titans
* 新接龍
* 傷心小棧
* 中文輸入法練習
* 战鹰!（英语：）
* 筆跡球
* Hold 'Em
* Mahjong Titans
* 踩地雷
* Purble Place
* 黑白棋
* 纸牌
* 連環新接龍
* Tinker

 |
|  |
| 应用程序 | 
* ActiveMovie
* Anytime Upgrade
* 通訊錄（英语：）
* 備份與還原中心
* Cardfile（英语：）
* CardSpace
* 連絡人
* 桌面小工具
* 診斷（英语：）
* DriveSpace
* DVD製作程式
* 傳真（英语：）
* 檔案管理員
* 檔案保護
* 美食
* 健康
* HyperTerminal（英语：）
* Outlook Express
* Windows Mail
* 媒体中心
* 會議空間
* 訊息中心（英语：）
* Messenger
* Mobile裝置中心
* NetMeeting
* 下一代安全计算基础
* NTBackup
* 旅遊
* 相片圖庫
* 程序管理器（英语：）
* WinHelp
* WinSAT
* 小作家
* Windows To Go
* 日记
* Movie Maker

 |
|  |
| 其他 | 
* Windows Services for UNIX
	+ POSIX子系统
	+ Interix（英语：）
* ScanDisk
* Windows視訊
* Windows相片檢視器
* Windows SideShow（英语：）
* 媒體控制介面

 |

 |

 |