診斷 Windows 執行階段元件錯誤條件
本文提供以 Managed 程式碼撰寫的 Windows 執行階段元件有何限制的其他資訊。其中詳述 Winmdexp.exe (Windows 執行階段中繼資料匯出工具) 中的錯誤訊息所提供的資訊,並補充在 C++ 和 Visual Basic 中建立 Windows 執行階段元件中提供的限制相關資訊。
本文並未列舉所有錯誤。本文討論的錯誤會依照一般類別分門別類,而每個類別都會有一個相關錯誤訊息的表格。搜尋訊息文字 (省略預留位置的特定值) 或訊息號碼。如果您在此處找不到您需要的資訊,請使用本文結尾處的意見反應按鈕協助我們改善文件。請納入錯誤訊息。或者,您也可以在 Microsoft Connect 網站上提報 bug。
本文章包含下列各節:
實作非同步模式時,錯誤訊息會提供不正確的型別
遺失 mscorlib.dll 和 (或) System.Runtime.dll 的參考
不允許運算子多載
一個類別的建構函式有相同數量的參數
對於具有相同數量參數的多載,必須指定預設值
命名空間錯誤,且輸出檔的名稱無效
匯出的型別不是有效的 Windows 執行階段型別
結構中包含不允許的欄位型別
成員簽章中的陣列限制
陣列參數必須指定陣列的內容是否可讀取或寫入
參數名稱為 "value" 的成員
用於實作非同步介面的錯誤訊息會提供不正確的型別
Managed Windows 執行階段元件無法實作表示非同步動作或作業 (IAsyncAction、IAsyncActionWithProgress<TProgress>、IAsyncOperation<TResult> 或 IAsyncOperationWithProgress<TResult, TProgress>) 的 Windows 執行階段介面。相反地,.NET Framework 會提供 AsyncInfo 類別,用來在 Windows 執行階段元件中產生非同步作業。當您嘗試以不正確的方式實作非同步介面時,Winmdexp.exe 顯示的錯誤訊息會根據這個類別的舊名稱 AsyncInfoFactory 指出這個類別,因為 .NET Framework 不再包含 AsyncInfoFactory 類別。
錯誤代碼 |
訊息文字 |
---|---|
WME1084 |
型別 '{0}' 實作了 Windows 執行階段非同步介面 '{1}'。Windows 執行階段型別不能實作非同步介面。請使用 System.Runtime.InteropServices.WindowsRuntime.AsyncInfoFactory 類別產生非同步作業,以匯出到 Windows 執行階段。 |
遺失 mscorlib.dll 或 System.Runtime.dll 的參考
只有從命令列使用 Winmdexp.exe 時,才會發生此問題。建議您使用 /reference 選項,從 .NET Framework 核心參考組件納入 mscorlib.dll 與 System.Runtime.dll 的參考,這些組件位於 "%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5" 中 (在 32 位元電腦上位於 "%ProgramFiles%\..." 中)。
錯誤代碼 |
訊息文字 |
---|---|
WME1009 |
未參考 mscorlib.dll。必須參考此中繼資料檔,才能正確匯出。 |
WME1090 |
無法判斷核心參考組件。請確定使用 /reference 參數來參考 mscorlib.dll 與 System.Runtime.dll。 |
不允許運算子多載
在使用 Managed 程式碼撰寫的 Windows 執行階段元件中,您無法公開公用型別的多載運算子。
注意事項 |
---|
在錯誤訊息中會以運算子的中繼資料名稱來識別運算子,例如 op_Addition、op_Multiply、op_ExclusiveOr、op_Implicit (隱含轉換) 等。 |
錯誤代碼 |
訊息文字 |
---|---|
WME1087 |
'{0}' 是運算子多載。在 Windows 執行階段中,Managed 型別無法公開運算子多載。 |
一個類別的建構函式有相同數量的參數
在 Windows 執行階段中,一個類別只能有一個具有指定數量參數的建構函式,例如,您不能有一個建構函式具有型別 String 的單一參數,同時又有一個建構函式具有型別 int (在 Visual Basic 中為Integer) 的單一參數。唯一的解決方法是對每個建構函式使用不同數量的參數。
錯誤代碼 |
訊息文字 |
---|---|
WME1099 |
型別 '{0}' 有多個具有 '{1}' 個引數的建構函式。Windows 執行階段型別不能有引數的相同數目的多個建構函式。 |
對於具有相同數量參數的多載,必須指定預設值
在 Windows 執行階段中,只有將某個多載指定為預設多載後,多載方法才可以有相同數量的參數。請參閱在 C++ 和 Visual Basic 中建立 Windows 執行階段元件中的「多載方法」。
錯誤代碼 |
訊息文字 |
---|---|
WME1059 |
'{1}.{2}' 有多個 {0} 參數多載以 Windows.Foundation.Metadata.DefaultOverloadAttribute 裝飾。 |
WME1085 |
{1}.{2} 的 {0} 參數多載只能以 Windows.Foundation.Metadata.DefaultOverloadAttribute 裝飾一個方法,而將其指定為預設多載。 |
命名空間錯誤,且輸出檔的名稱無效
在 Windows 執行階段中,Windows 中繼資料 (.winmd) 檔案中的所有公用型別必須位於共用 .winmd 檔案名稱的命名空間中,或位於該檔案名稱的子命名空間中。例如,如果您的 Visual Studio 2012 專案名稱為 A.B (也就是說,您的 Windows 執行階段元件為 A.B.winmd),則此專案可包含公用類別 A.B.Class1 與 A.B.C.Class2,但不可包含 A.Class3 (WME0006) 或 D.Class4 (WME1044)。
注意事項 |
---|
這些限制僅適用於公用型別,而不適用於您的實作所使用的私用型別。 |
以 A.Class3 為例,您可以將 Class3 移至其他命名空間,或將 Windows 執行階段元件的名稱變更為 A.winmd。雖然 WME0006 是警告,但您應將其視為錯誤。在上述範例中,呼叫 A.B.winmd 的程式碼將找不到 A.Class3。
以 D.Class4 為例,沒有任何檔案名稱可同時包含 D.Class4 與 A.B 命名空間中的類別,因此變更 Windows 執行階段元件的名稱是不可行的。您可以將 D.Class4 移至另一個命名空間,或將其放在另一個 Windows 執行階段元件中。
檔案系統無法區分大小寫,因此不允許只有大小寫不同的命名空間 (WME1067)。
您的元件至少必須包含一個 public sealed 型別 (在 Visual Basic 中為 Public NotInheritable)。否則將會出現 WME1042 或 WME1043,視您的元件是否包含私用型別而定。
Windows 執行階段元件中的型別不可與命名空間同名 (WME1068)。
警告
如果您直接呼叫 Winmdexp.exe,而未使用 /out 選項為您的 Windows 執行階段元件指定名稱,Winmdexp.exe 即會嘗試產生包含元件中所有命名空間的名稱。為命名空間重新命名,可變更元件的名稱。
錯誤代碼 |
訊息文字 |
---|---|
WME0006 |
'{0}' 對此組件而言不是有效的 winmd 檔案名稱。Windows 中繼資料檔中的所有型別,都必須存在於命名空間裡以檔案名稱暗示的子命名空間中。不存在於這類子命名空間中的型別,將無法在執行階段中找出。在這個組件中,可做為檔案名稱的最小通用命名空間是 '{1}'。 |
WME1042 |
輸入模組至少必須包含一個位於命名空間內的公用型別。 |
WME1043 |
輸入模組至少必須包含一個位於命名空間內的公用型別。位於命名空間內的型別都是私用的。 |
WME1044 |
公用型別有命名空間 ('{1}') 未與其他命名空間 ('{0}') 共用通用的前置詞。Windows 中繼資料檔中的所有型別,都必須存在於命名空間裡以檔案名稱暗示的子命名空間中。 |
WME1067 |
命名空間名稱不可只有大小寫不同:'{0}','{1}'。 |
WME1068 |
型別 '{0}' 不可與命名空間 '{1}' 同名。 |
匯出的型別不是有效的 Windows 執行階段型別
元件的公用介面必須只公開 Windows 執行階段型別。但是,.NET Framework 針對許多在 .NET Framework 與 Windows 執行階段中只有些許差異的通用型別,提供了對應。這可讓 .NET Framework 開發人員使用熟悉的型別,而不用學習新的型別。您可以在元件的公用介面中使用這些對應的 .NET Framework 型別。請參閱在 C++ 和 Visual Basic 中建立 Windows 執行階段元件與 Windows 執行階段型別的 .NET Framework 對應中的「在 Windows 執行階段元件中宣告型別」與「將 Windows 執行階段型別傳送至 Managed 程式碼」。
其中有許多對應都是介面。例如,IList<T> 會對應至 Windows 執行階段介面 IVector<T>。如果您使用 List<string> (在 Visual Basic 中為 List(Of String)) 做為參數型別,而非使用 IList<string>,則 Winmdexp.exe 會提供包含所有由 List<T> 實作之對應介面的替代項目清單。如果您使用 List<Dictionary<int, string>> 之類的巢狀泛型型別 (在 Visual Basic 中為 List(Of Dictionary(Of Integer, String))),則 Winmdexp.exe 會提供適用於各層巢狀的選項。這些清單可能會變得很冗長。
一般而言,最接近型別的介面就是最好的選擇。以 Dictionary<int, string> 為例,IDictionary<int, string> 最有可能是最佳選擇。
重要
JavaScript 會使用 Managed 型別所實作的介面清單中第一個出現的介面。例如,如果您將 Dictionary<int, string> 傳回至 JavaScript 程式碼,它將會顯示為 IDictionary<int, string>,無論您將哪個介面指定為傳回型別。這表示,如果第一個介面不包含出現在後續介面上的成員,該成員即不會對 JavaScript 顯示。
警告
如果 JavaScript 會使用您的元件,請避免使用非泛型 IList 和 IEnumerable 介面。這兩個介面會分別對應至 IBindableVector 與 IBindableIterator。它們支援 XAML 控制項的繫結,且不會對 JavaScript 顯示。JavaScript 會發出執行階段錯誤「函式 'X' 具有無效簽章,無法呼叫」。
錯誤代碼 |
訊息文字 |
---|---|
WME1033 |
方法 '{0}' 具有型別 '{2}' 的參數 '{1}'。'{2}' 不是有效的 Windows 執行階段參數型別。 |
WME1038 |
方法 '{0}' 在其簽章中具有型別 '{1}' 的參數。雖然這個型別不是有效的 Windows 執行階段型別,但它可實作屬於有效 Windows 執行階段型別的介面。請考慮變更方法簽章,以改用下列其中一種型別:'{2}'。 |
WME1039 |
方法 '{0}' 在其簽章中具有型別 '{1}' 的參數。雖然這個泛型型別不是有效的 Windows 執行階段型別,但此型別或其泛型參數可實作屬於有效 Windows 執行階段型別的介面。{2}
注意事項
針對 {2},Winmdexp.exe 會附加替代項目清單,例如「請考慮將方法簽章中的型別 'System.Collections.Generic.List<T>' 變更為下列其中一種型別:System.Collections.Generic.IList<T>、System.Collections.Generic.IReadOnlyList<T>、System.Collections.Generic.IEnumerable<T>」。
|
WME1040 |
方法 '{0}' 在其簽章中具有型別 '{1}' 的參數。請不要使用 Managed 工作型別,而應使用 Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation,或其中一個其他的 Windows 執行階段非同步介面。標準 .NET 等候模式也適用於這些介面。如需將 Managed 工作物件轉換成 Windows 執行階段非同步介面的詳細資訊,請參閱 System.Runtime.InteropServices.WindowsRuntime.AsyncInfo。 |
結構中包含不允許的欄位型別
在 Windows 執行階段中,結構只能包含欄位,且只有結構可包含欄位。這些欄位必須是公用的。有效的欄位型別包括列舉、結構與基本型別。
錯誤代碼 |
訊息文字 |
---|---|
WME1060 |
結構 '{0}' 具有型別 '{2}' 的欄位 '{1}'。'{2}' 不是有效的 Windows 執行階段欄位型別。Windows 執行階段結構中的每個欄位,都只能是 UInt8、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、布林值、字串、列舉,或本身即為結構。 |
成員簽章中的陣列限制
在 Windows 執行階段中,成員簽章中的陣列必須是下限為 0 (零) 的一維陣列。不允許 myArray[][] 之類的巢狀陣列型別 (在 Visual Basic 中為 myArray()())。
注意事項 |
---|
這項限制不適用於您在自己的實作內部使用的陣列。 |
錯誤代碼 |
訊息文字 |
---|---|
WME1034 |
方法 '{0}' 在其簽章中具有型別為 '{1}'、下限非零的陣列。Windows 執行階段方法簽章的陣列必須以零為下限。 |
WME1035 |
方法 '{0}' 在其簽章中具有型別 '{1}' 的多維陣列。Windows 執行階段方法簽章中的陣列必須是一維的。 |
WME1036 |
方法 '{0}' 在其簽章中具有型別 '{1}' 的巢狀陣列。Windows 執行階段方法簽章中的陣列不可為巢狀。 |
陣列參數必須指定陣列的內容是否可讀取或寫入
在 Windows 執行階段中,參數必須是唯讀或唯寫的。參數不可標示 ref (在 Visual Basic 中為不含 OutAttribute 屬性的 ByRef)。這適用於陣列的內容,因此陣列參數必須指出陣列內容是否為唯讀或唯寫。這項指示對於 out 參數是明確的 (在 Visual Basic 中為具有 OutAttribute 屬性的 ByRef 參數),但是以傳值方式傳遞的陣列參數 (在 Visual Basic 中為 ByVal) 則必須標示。請參閱傳遞陣列給 Windows 執行階段元件。
錯誤代碼 |
訊息文字 |
---|---|
WME1101 |
方法 '{0}' 有屬於陣列、且同時具有 {2} 與 {3} 的參數 '{1}'。在 Windows 執行階段中,陣列參數的內容必須是可讀取或可寫入的。請從 '{1}' 移除其中一個屬性。 |
WME1102 |
方法 '{0}' 有屬於陣列、但具有 {2} 的輸出參數 '{1}'。在 Windows 執行階段中,輸出陣列的內容是可寫入的。請從 '{1}' 中移除該屬性。 |
WME1103 |
方法 '{0}' 有屬於陣列、且具有 System.Runtime.InteropServices.InAttribute 或 System.Runtime.InteropServices.OutAttribute 的參數 '{1}'。在 Windows 執行階段中,陣列參數必須具有 {2} 或 {3}。請移除這些屬性,或視需要以適當的 Windows 執行階段屬性加以取代。 |
WME1104 |
方法 '{0}' 有不是陣列、且具有 {2} 或 {3} 的參數 '{1}'。Windows 執行階段不支援以 {2} 或 {3} 標示非陣列參數。 |
WME1105 |
方法 '{0}' 有具有 System.Runtime.InteropServices.InAttribute 或 System.Runtime.InteropServices.OutAttribute 的參數 '{1}'。Windows 執行階段不支援以 System.Runtime.InteropServices.InAttribute 或 System.Runtime.InteropServices.OutAttribute 標示參數。請考慮移除 System.Runtime.InteropServices.InAttribute,並以 'out' 修飾詞取代 System.Runtime.InteropServices.OutAttribute。 方法 '{0}' 有具有 System.Runtime.InteropServices.InAttribute 或 System.Runtime.InteropServices.OutAttribute 的參數 '{1}'。Windows 執行階段僅支援以 System.Runtime.InteropServices.OutAttribute 標示 ByRef 參數,而不支援這些屬性的其他用法。 |
WME1106 |
方法 '{0}' 具有屬於陣列的參數 '{1}'。在 Windows 執行階段中,陣列參數的內容必須是可讀取或可寫入的。請將 {2} 或 {3} 套用至 '{1}'。 |
參數名稱為 "value" 的成員
在 Windows 執行階段中,傳回值會視為輸出參數,且參數名稱必須是唯一的。根據預設,Winmdexp.exe 會爲傳回值指定名稱 "value"。如果您的方法有名稱為 "value" 的參數,就會發生 WME1092 錯誤。有兩種方式可以修正這種情形:
使用 "value" 以外的名稱命名您的參數 (在屬性存取子中,則為 "returnValue" 以外的名稱)。
使用 ReturnValueNameAttribute 屬性變更傳回值的名稱,如下所示:
using System.Runtime.InteropServices; using System.Runtime.InteropServices.WindowsRuntime; [return: ReturnValueName("average")] public int GetAverage(out int lowValue, out int highValue)
Imports System.Runtime.InteropServices Imports System.Runtime.InteropServices.WindowsRuntime Public Function GetAverage(<Out> ByRef lowValue As Integer, _ <Out> ByRef highValue As Integer) As <ReturnValueName("average")> String
注意事項 如果您變更傳回值的名稱,且新名稱與另一個參數的名稱衝突,就會發生 WME1091 錯誤。
JavaScript 程式碼可依名稱存取方法的輸出參數,包括傳回值在內。如需範例,請參閱 ReturnValueNameAttribute 屬性。
錯誤代碼 |
訊息文字 |
---|---|
WME1091 |
方法 '{0}' 具有與參數名稱同名的傳回值 '{1}'。Windows 執行階段的方法參數和傳回值必須具有唯一的名稱。 |
WME1092 |
方法 '{0}' 具有名稱為 '{1}' 的參數,該名稱與預設傳回值名稱相同。請考慮使用不同的參數名稱,或使用 System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute 明確指定傳回值的名稱。
注意事項
屬性存取子的預設名稱為 "returnValue",而其他所有方法的預設名稱為 "value"。
|
請參閱
參考
Winmdexp.exe (Windows 執行階段中繼資料匯出工具)