Share via


診斷 Windows 執行階段元件錯誤條件

本文提供以 Managed 程式碼撰寫的 Windows 執行階段元件有何限制的其他資訊。其中詳述 Winmdexp.exe (Windows 執行階段中繼資料匯出工具) 中的錯誤訊息所提供的資訊,並補充在 C++ 和 Visual Basic 中建立 Windows 執行階段元件中提供的限制相關資訊。

本文並未列舉所有錯誤。本文討論的錯誤會依照一般類別分門別類,而每個類別都會有一個相關錯誤訊息的表格。搜尋訊息文字 (省略預留位置的特定值) 或訊息號碼。如果您在此處找不到您需要的資訊,請使用本文結尾處的意見反應按鈕協助我們改善文件。請納入錯誤訊息。或者,您也可以在 Microsoft Connect 網站上提報 bug。

本文章包含下列各節:

  • 實作非同步模式時,錯誤訊息會提供不正確的型別

  • 遺失 mscorlib.dll 和 (或) System.Runtime.dll 的參考

  • 不允許運算子多載

  • 一個類別的建構函式有相同數量的參數

  • 對於具有相同數量參數的多載,必須指定預設值

  • 命名空間錯誤,且輸出檔的名稱無效

  • 匯出的型別不是有效的 Windows 執行階段型別

  • 結構中包含不允許的欄位型別

  • 成員簽章中的陣列限制

  • 陣列參數必須指定陣列的內容是否可讀取或寫入

  • 參數名稱為 "value" 的成員

用於實作非同步介面的錯誤訊息會提供不正確的型別

Managed Windows 執行階段元件無法實作表示非同步動作或作業 (IAsyncActionIAsyncActionWithProgress<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 會使用您的元件,請避免使用非泛型 IListIEnumerable 介面。這兩個介面會分別對應至 IBindableVectorIBindableIterator。它們支援 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 執行階段中繼資料匯出工具)

概念

在 C++ 和 Visual Basic 中建立 Windows 執行階段元件