處理佇列元件中的錯誤
有時候,訊息無法成功傳遞至其預定目的地的情況,通常是因為系統或設定發生問題。 例如,訊息可能會導向至不存在的佇列,或目的地佇列可能不是處於接收狀態。 訊息移動器是一種工具,可將所有失敗 的消息佇列 訊息從一個佇列移至另一個佇列,以便重試訊息。 訊息移動器公用程式是可使用 VBScript 叫用的 Automation 物件。
Components Services 管理員 istrative Tool
不適用。
Visual Basic
下列範例程式代碼示範如何建立 MessageMover 對象、設定必要的屬性,以及起始傳輸。 若要從 Visual Basic 使用它,請新增 COM+ 服務類型連結庫的參考。
注意
若要使用 MessageMover 物件,您必須在電腦上安裝 Message Queuing,且 AppName 指定的應用程式必須啟用佇列。 如需安裝消息佇列的相關信息,請參閱 [開始] 功能表上的 [說明及支援]。
Function MyMessageMover( _
strSource As String, _
strDest As String _
) As Boolean ' Return False if any errors occur.
MyMessageMover = False ' Initialize the function.
On Error GoTo My_Error_Handler ' Initialize error handling.
Dim lngMovedMessages As Long
Dim objMessageMover As COMSVCSLib.MessageMover
Set objMessageMover = CreateObject("QC.MessageMover")
objMessageMover.SourcePath = strSource
objMessageMover.DestPath = strDest
lngMovedMessages = objMessageMover.MoveMessages
MsgBox lngMovedMessages & " messages moved from " & _
strSource & " to " & strDest
MyMessageMover = True ' Successful end to procedure
Set objMessageMover = Nothing
Exit Function
My_Error_Handler: ' Replace with specific error handling.
MsgBox "Error # " & Err.Number & " (Hex: " & Hex(Err.Number) _
& ")" & vbNewLine & Err.Description
Set objMessageMover = Nothing
lngMovedMessages = -1
End Function
下列 Visual Basic 程式代碼示範如何呼叫 MyMessageMover 函式。
Sub Main()
' Replace AppName with the name of a COM+ application.
If Not MyMessageMover(".\private$\AppName_deadqueue", ".\AppName") Then
MsgBox "MyMessageMover failed."
End If
End Sub
訊息的來源路徑是最終的待用佇列。 它是死佇列,這是私人消息佇列佇列,並稱為AppName_deadqueue。 如果交易在第五個重試佇列上嘗試時重複中止,則會在此移動訊息。 使用訊息行動工具,您可以將訊息移回第一個佇列,稱為 AppName。 如需重試佇列的詳細資訊,請參閱 伺服器端錯誤。
如果佇列屬性允許,訊息行動器會轉換訊息,以便在行動期間失敗時不會遺失或複製訊息。 此工具會保留將訊息從一個佇列移至另一個佇列時可保留的所有訊息屬性。
如果訊息是由 COM+ 佇列元件呼叫所產生,訊息行動器公用程式會在訊息在佇列之間移動訊息時,保留原始呼叫端的安全性識別元。 如果目的地和來源佇列都是交易式,則整個作業會以過渡方式完成。 如果來源或目的地佇列不是交易式,則作業不會在交易下執行。 非交易式移動未預期的失敗(例如當機)和重新啟動可能會複製失敗時所移動的訊息。
C/C++
下列範例程式代碼示範如何建立 MessageMover 對象、設定必要的屬性,以及起始傳輸。 ErrorDescription 方法描述於 解譯錯誤碼。
注意
若要使用 MessageMover 物件,您必須在電腦上安裝 Message Queuing,且 AppName 指定的應用程式必須啟用佇列。 如需安裝消息佇列的相關信息,請參閱 [開始] 功能表上的 [說明及支援]。
#include <windows.h>
#include <stdio.h>
#import "C:\WINDOWS\system32\ComSvcs.dll"
#include "ComSvcs.h"
#include "StrSafe.h"
BOOL MyMessageMover (OLECHAR* szSource, OLECHAR* szDest) {
IUnknown * pUnknown = NULL;
IMessageMover * pMover = NULL;
HRESULT hr = S_OK;
BSTR bstrSource = NULL;
BSTR bstrDest = NULL;
unsigned int uMaxLen = 255; // Maximum length of szMyApp
try {
// Test the input strings to make sure they're OK to use.
hr = StringCchLengthW(szSource, uMaxLen, NULL);
if (FAILED (hr)) throw(hr);
hr = StringCchLengthW(szDest, uMaxLen, NULL);
if (FAILED (hr)) throw(hr);
// Convert the input strings to BSTRs.
bstrSource = SysAllocString(szSource);
bstrDest = SysAllocString(szDest);
// Create a MessageMover object and get its IUnknown.
hr = CoCreateInstance(CLSID_MessageMover, NULL,
CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
if (FAILED (hr)) throw(hr);
// Get the IMessageMover interface.
hr = pUnknown->QueryInterface(IID_IMessageMover, (void**)&pMover);
if (FAILED (hr)) throw(hr);
// Put the source and destination files.
hr = pMover->put_SourcePath(bstrSource);
if (FAILED (hr)) throw(hr);
hr = pMover->put_DestPath(bstrDest);
if (FAILED (hr)) throw(hr);
// Move the messages.
LONG lCount = -1;
hr = pMover->MoveMessages(&lCount);
if (FAILED (hr)) throw(hr);
printf("%ld messages moved from %S to %S.\n",
lCount, bstrSource, bstrDest);
// Clean up.
SysFreeString(bstrDest);
SysFreeString(bstrSource);
pUnknown->Release();
pUnknown = NULL;
pMover->Release();
pMover = NULL;
return (TRUE);
} // try
catch(HRESULT hr) { // Replace with specific error handling.
printf("Error # %#x: ", hr);
ErrorDescription(hr);
SysFreeString(bstrDest);
SysFreeString(bstrSource);
if (NULL != pUnknown) pUnknown->Release();
pUnknown = NULL;
if (NULL != pMover) pMover->Release();
pMover = NULL;
return (FALSE);
}catch(...) {
printf("An unexpected exception occurred.\n");
throw;
}
} // MyMessageMover
下列 C++ 程式代碼示範如何呼叫 MyMessageMover 函式。
#include <windows.h>
#include <stdio.h>
#define _WIN32_DCOM // To use CoInitializeEx()
void main()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED (hr)) {
printf("CoInitializeEx failed: Error # %#x\n", hr);
exit(0); // Replace with specific error handling.
}
if (! MyMessageMover(L".\\private$\\AppName_deadqueue",
L".\\AppName"))
printf("MyMessageMover failed.\n");
CoUninitialize();
}
訊息的來源路徑是最終的待用佇列。 它是死佇列,這是私人消息佇列佇列,並稱為AppName_deadqueue。 如果交易在第五個重試佇列上嘗試時重複中止,則會在此移動訊息。 使用訊息行動工具,您可以將訊息移回第一個佇列,稱為 AppName。 如需重試佇列的詳細資訊,請參閱 伺服器端錯誤。
如果佇列屬性允許,訊息行動器會轉換訊息,以便在行動期間失敗時不會遺失或複製訊息。 此工具會保留將訊息從一個佇列移至另一個佇列時可保留的所有訊息屬性。
如果訊息是由 COM+ 佇列元件呼叫所產生,訊息行動器公用程式會在訊息在佇列之間移動訊息時,保留原始呼叫端的安全性識別元。 如果目的地和來源佇列都是交易式,則整個作業會以過渡方式完成。 如果來源或目的地佇列不是交易式,則作業不會在交易下執行。 非交易式移動未預期的失敗(例如當機)和重新啟動可能會複製失敗時所移動的訊息。
備註
COM+ 會藉由移動無法進入不同「最終休息」佇列的訊息來處理伺服器端 (player) 中止,使其脫離。 接聽程式和播放機無法持續迴圈中止的訊息。 在許多情況下,中止的交易可以在伺服器上採取動作來修正。
相關主題