Compartir a través de


Diagnóstico de condiciones de error de componentes de Windows Runtime

En este artículo se proporciona información adicional sobre las restricciones en los componentes de Windows Runtime escritos con código administrado. Se expande sobre la información proporcionada en los mensajes de error de Winmdexp.exe (Herramienta de exportación de metadatos de Windows Runtime), y complementa la información sobre las restricciones proporcionadas en componentes de Windows Runtime con C# y Visual Basic.

En este artículo no se tratan todos los errores. Los errores que se describen aquí se agrupan por categoría general y cada categoría incluye una tabla de mensajes de error asociados. Busque texto de mensaje (omitiendo valores específicos para marcadores de posición) o el número de mensaje. Si no encuentra la información que necesita aquí, ayúdanos a mejorar la documentación mediante el botón de comentarios al final de este artículo. Incluya el mensaje de error. Como alternativa, puede presentar un error en el sitio web de Microsoft Connect.

Mensaje de error al implementar la interfaz asincrónica que devuelve un tipo erróneo.

Los componentes administrados de Windows Runtime no pueden implementar las interfaces de la Plataforma universal de Windows (UWP) que representan acciones o operaciones asincrónicas (IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult>o IAsyncOperationWithProgress<TResult, TProgress>). En su lugar, .NET proporciona la clase AsyncInfo para generar operaciones asincrónicas en componentes de Windows Runtime. El mensaje de error que Winmdexp.exe muestra cuando intenta implementar una interfaz asincrónica hace referencia incorrectamente a esta clase por su nombre anterior, AsyncInfoFactory. .NET ya no incluye la clase AsyncInfoFactory.

Número de error Texto del mensaje
WME1084 El tipo '{0}' implementa la interfaz asincrónica de Windows Runtime '{1}'. Los tipos de Windows Runtime no pueden implementar interfaces asincrónicas. Use la clase System.Runtime.InteropServices.WindowsRuntime.AsyncInfoFactory para generar operaciones asincrónicas para la exportación a Windows Runtime.

Nota Los mensajes de error que hacen referencia a Windows Runtime usan una terminología antigua. Esto se conoce ahora como la Plataforma universal de Windows (UWP). Por ejemplo, los tipos de Windows Runtime ahora se denominan tipos de UWP.

Faltan referencias a mscorlib.dll o System.Runtime.dll

Este problema solo se produce cuando se usa Winmdexp.exe desde la línea de comandos. Se recomienda usar la opción /reference para incluir referencias a mscorlib.dll y System.Runtime.dll de los ensamblados de referencia principal de .NET Framework, que se encuentran en "%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\. NETCore\v4.5" ("%ProgramFiles%\..." en un equipo de 32 bits).

Número de error Texto del mensaje
WME1009 No se hizo referencia a mscorlib.dll. Se requiere una referencia a este archivo de metadatos para exportar correctamente.
WME1090 No se pudo determinar el ensamblado de referencia principal. Asegúrese de que se haga referencia a mscorlib.dll y System.Runtime.dll mediante el modificador /reference.

No se permite la sobrecarga del operador

En un componente de Windows Runtime escrito en código administrado, no se pueden exponer operadores sobrecargados en tipos públicos.

Nota En el mensaje de error, el operador se identifica por su nombre de metadatos, como op_Addition, op_Multiply, op_ExclusiveOr, op_Implicit (conversión implícita), etc.

Número de error Texto del mensaje
WME1087 '{0}' es una sobrecarga del operador. Los tipos administrados no pueden exponer sobrecargas de operador en Windows Runtime.

Los constructores de una clase tienen el mismo número de parámetros

En la UWP, una clase solo puede tener un constructor con un número determinado de parámetros; Por ejemplo, no puede tener un constructor que tenga un único parámetro de tipo String y otro que tenga un único parámetro de tipo int (integer en Visual Basic). La única solución alternativa es usar un número diferente de parámetros para cada constructor.

Número de error Texto del mensaje
WME1099 El tipo '{0}' tiene varios constructores con '{1}' argumento(s). Los tipos de Windows Runtime no pueden tener varios constructores con el mismo número de argumentos.

Debe especificar un valor predeterminado para las sobrecargas que tienen el mismo número de parámetros.

En UWP, los métodos sobrecargados solo pueden tener el mismo número de parámetros si se especifica una sobrecarga como sobrecarga predeterminada. Vea "Métodos sobrecargados" en componentes de Windows Runtime con C# y Visual Basic.

Número de error Texto del mensaje
WME1059 Varias sobrecargas de parámetros de {0}de "{1}.{2}' están decoradas con Windows.Foundation.Metadata.DefaultOverloadAttribute.
WME1085 Sobrecargas de {0}parámetro de {1}.{2} debe tener exactamente un método especificado como sobrecarga predeterminada decorandolo con Windows.Foundation.Metadata.DefaultOverloadAttribute.

Errores en el espacio de nombres y nombres no válidos para el archivo de salida

En la Plataforma universal de Windows, todos los tipos públicos de un archivo de metadatos de Windows (.winmd) deben estar en un espacio de nombres que comparta el nombre de archivo .winmd o en los espacios de nombres secundarios del nombre de archivo. Por ejemplo, si el proyecto de Visual Studio se denomina A.B (es decir, el componente de Windows Runtime es A.B.winmd), puede contener clases públicas A.B.Class1 y A.B.C.Class2, pero no A.Class3 (WME0006) o D.Class4 (WME1044).

Nota Estas restricciones solo se aplican a los tipos públicos, no a los tipos privados usados en la implementación.

En el caso de A.Class3, puedes mover Class3 a otro espacio de nombres o cambiar el nombre del componente de Windows Runtime a A.winmd. Aunque WME0006 es una advertencia, deberías tratarla como un error. En el ejemplo anterior, el código que llama a A.B.winmd no podrá encontrar A.Class3.

En el caso de D.Class4, ningún nombre de archivo puede contener tanto D.Class4 como clases en el espacio de nombres A.B, por lo que cambiar el nombre del componente de Windows Runtime no es una opción. Puedes mover D.Class4 a otro espacio de nombres o colocarlo en otro componente de Windows Runtime.

El sistema de archivos no puede distinguir entre mayúsculas y minúsculas, por lo que no se permiten espacios de nombres que difieran solo por su capitalización (WME1067).

El componente debe contener al menos un tipo de sellado público ( public NotInheritable en Visual Basic). Si no es así, obtendrá WME1042 o WME1043, dependiendo de si el componente contiene tipos privados.

Un tipo en un componente de Windows Runtime no puede tener un nombre que sea el mismo que un espacio de nombres (WME1068).

Precaución Si llamas directamente a Winmdexp.exe y no usas la opción /out para especificar un nombre para el componente de Windows Runtime, Winmdexp.exe intenta generar un nombre que incluya todos los espacios de nombres del componente. Cambiar el nombre de los espacios de nombres puede cambiar el nombre de su componente.

 

Número de error Texto del mensaje
WME0006 '{0}' no es un nombre de archivo winmd válido para este ensamblado. Todos los tipos de un archivo de metadatos de Windows deben existir dentro de un subespacio de nombres que pertenece al espacio de nombres implícito en el nombre de archivo. Los tipos que no existen en este subespacio de nombres no se pueden encontrar en tiempo de ejecución. En este ensamblado, el espacio de nombres más pequeño común que podría servir como nombre de archivo es "{1}".
WME1042 El módulo de entrada debe contener al menos un tipo público que se encuentre dentro de un espacio de nombres.
WME1043 El módulo de entrada debe contener al menos un tipo público que se encuentre dentro de un espacio de nombres. Los únicos tipos que se encuentran dentro de los espacios de nombres son privados.
WME1044 Un tipo público tiene un espacio de nombres ("{1}") que no comparte ningún prefijo común con otros espacios de nombres ("{0}" ). Todos los tipos de un archivo de metadatos de Windows deben existir dentro de un subespacio de nombres que pertenece al espacio de nombres implícito en el nombre de archivo.
WME1067 Los espacios de nombres no pueden diferir solo por cambio de mayúsculas y minúsculas: '{0}', '{1}'.
WME1068 El tipo '{0}' no puede tener el mismo nombre que el espacio de nombres '{1}'.

Exportación de tipos que no son tipos válidos de la Plataforma universal de Windows

La interfaz pública del componente solo debe exponer tipos de UWP. Sin embargo, .NET proporciona asignaciones para varios tipos usados habitualmente que son ligeramente diferentes en .NET y UWP. Esto permite al desarrollador de .NET trabajar con tipos conocidos en lugar de aprender nuevos. Puede usar estos tipos de .NET asignados en la interfaz pública del componente. Véase "Declarar tipos en componentes de Windows Runtime" y "Pasar tipos de Plataforma Universal de Windows al código administrado" en Componentes de Windows Runtime con C# y Visual Basic, y asignaciones .NET de tipos de Windows Runtime.

Muchos de estos mapeos son interfaces. Por ejemplo, IList<T> se mapea a la interfaz UWP IVector<T>. Si usa List<cadena> (List(Of String) en Visual Basic) en lugar de IList<cadena> como tipo de parámetro, Winmdexp.exe proporciona una lista de alternativas que incluye todas las interfaces mapeadas implementadas por List<T>. Si usa tipos genéricos anidados, como List<Dictionary<int, string>> (List(Of Dictionary(Of Integer, String)) en Visual Basic), Winmdexp.exe ofrece opciones para cada nivel de anidamiento. Estas listas pueden llegar a ser bastante largas.

En general, la mejor opción es la interfaz más cercana al tipo. Por ejemplo, para Dictionary<int, string>, la mejor opción es IDictionary<int, string>.

Importante JavaScript usa la interfaz que aparece primero en la lista de interfaces que implementa un tipo administrado. Por ejemplo, si devuelve Dictionary<int, string> a código JavaScript, aparece como IDictionary<int, string> independientemente de la interfaz que especifique como tipo de valor devuelto. Esto significa que si la primera interfaz no incluye un miembro que aparece en interfaces posteriores, ese miembro no es visible para JavaScript.

Precaución Evitar el uso de las interfaces no genéricas IList y IEnumerable si el componente será utilizado por JavaScript. Estas interfaces se asignan a IBindableVector y IBindableIterator, respectivamente. Admiten el enlace para controles XAML y son invisibles para JavaScript. JavaScript emite el error en tiempo de ejecución "La función 'X' tiene una firma no válida y no se puede llamar a él".

 

Número de error Texto del mensaje
WME1033 El método '{0}' tiene el parámetro '{1}' de tipo '{2}'. '{2}' no es un tipo de parámetro válido de Windows Runtime.
WME1038 El método "{0}" tiene un parámetro de tipo "{1}" en su firma. Aunque este tipo no es un tipo válido de Windows Runtime, implementa interfaces que son tipos válidos de Windows Runtime. Considere la posibilidad de cambiar la firma del método para usar uno de los siguientes tipos en su lugar: "{2}".
WME1039

El método "{0}" tiene un parámetro de tipo "{1}" en su firma. Aunque este tipo genérico no es un tipo válido de Windows Runtime, el tipo o sus parámetros genéricos implementan interfaces que son tipos válidos de Windows Runtime. {2}

> **Nota** Para {2}, Winmdexp.exe anexa una lista de alternativas, por ejemplo, "Considere la posibilidad de cambiar el tipo "System.Collections.Generic.List<T>" en la firma del método a uno de los siguientes tipos en su lugar: "System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.Generic.IEnumerable<T>"".
WME1040 El método "{0}" tiene un parámetro de tipo "{1}" en su firma. En lugar de usar un tipo de tarea administrada, use Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation o una de las otras interfaces asincrónicas de Windows Runtime. El patrón await estándar de .NET también se aplica a estas interfaces. Consulta System.Runtime.InteropServices.WindowsRuntime.AsyncInfo para obtener más información sobre cómo convertir objetos de tarea administrados en interfaces asincrónicas de Windows Runtime.

 

Estructuras que contienen campos de tipos no permitidos

En UWP, una estructura solo puede contener campos y solo las estructuras pueden contener campos. Esos campos deben ser públicos. Los tipos de campo válidos incluyen enumeraciones, estructuras y tipos primitivos.

Número de error Texto del mensaje
WME1060 Estructura '{0}' tiene el campo '{1}' de tipo '{2}'. '{2}' no es un tipo de campo válido de Windows Runtime. Cada campo de una estructura de Windows Runtime solo puede ser UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum o sí mismo una estructura.

 

Restricciones sobre matrices en firmas de miembros

En UWP, las matrices de las firmas de miembro deben ser unidimensionales con un límite inferior de 0 (cero). No se permiten tipos de matriz anidados, como myArray[][] (myArray()() en Visual Basic).

Nota Esta restricción no se aplica a las matrices que se usan internamente en la implementación.

 

Número de error Texto del mensaje
WME1034 El método '{0}' tiene una matriz de tipo '{1}' con límite inferior distinto de cero en su firma. Las matrices de las firmas de método de Windows Runtime deben tener un límite inferior de cero.
WME1035 El método '{0}' tiene una matriz multidimensional de tipo '{1}' en su firma. Las matrices en las firmas de los métodos de Windows Runtime deben ser unidimensionales.
WME1036 El método '{0}' tiene una matriz anidada de tipo '{1}' en su firma. Las firmas de métodos en Windows Runtime no pueden contener matrices anidadas.

 

Los parámetros de matriz deben especificar si el contenido de la matriz es legible o grabable.

En UWP, los parámetros deben ser de solo lectura o de solo escritura. No se pueden marcar los parámetros como ref (ByRef sin el atributo OutAttribute en Visual Basic). Esto se aplica al contenido de las matrices, por lo que los parámetros de matriz deben indicar si el contenido de la matriz es de solo lectura o de solo escritura. La dirección está clara para los parámetros (el parámetro ByRef con el atributo OutAttribute en Visual Basic), pero los parámetros de array que se pasan por valor (ByVal en Visual Basic) deben marcarse. Ver Pasar matrices a un componente de Windows Runtime.

Número de error Texto del mensaje
WME1101 El método '{0}' tiene el parámetro '{1}' que es una matriz, y que tiene tanto {2} como {3}. En Windows Runtime, los parámetros de la matriz de contenido deben ser legibles o grabables. Quite uno de los atributos de "{1}".
WME1102 El método '{0}' tiene un parámetro de salida '{1}' que es una matriz, pero que tiene {2}. En Windows Runtime, el contenido de las matrices de salida se puede escribir. Quite el atributo de "{1}".
WME1103 El método '{0}' tiene el parámetro '{1}' que es una matriz, y que tiene un System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. En Windows Runtime, los parámetros de matriz deben tener {2} o {3}. Quite estos atributos o reemplácelos por el atributo de Windows Runtime adecuado si es necesario.
WME1104 El método '{0}' tiene el parámetro '{1}' que no es una matriz, y que tiene un {2} o un {3}. Windows Runtime no admite el marcado de parámetros que no son de matriz con {2} o {3}.
WME1105 El método '{0}' tiene el parámetro '{1}' con un System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Windows Runtime no admite el marcado de parámetros con System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Considere la posibilidad de quitar System.Runtime.InteropServices.InAttribute y reemplazar System.Runtime.InteropServices.OutAttribute por el modificador "out". El método '{0}' tiene el parámetro '{1}' con un System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Windows Runtime solo admite el marcado de parámetros ByRef con System.Runtime.InteropServices.OutAttribute y no admite otros usos de esos atributos.
WME1106 El método "{0}" tiene el parámetro "{1}" que es una matriz. En Windows Runtime, el contenido de los parámetros de matriz debe ser legible o grabable. Aplique {2} o {3} a "{1}".

Miembro con un parámetro denominado "value"

En UWP, los valores devueltos se consideran parámetros de salida y los nombres de los parámetros deben ser únicos. De forma predeterminada, Winmdexp.exe proporciona al valor devuelto el nombre "value". Si el método tiene un parámetro denominado "value", obtendrá el error WME1092. Hay dos maneras de corregir esto:

  • Asigne a su parámetro un nombre diferente de "value" (en los descriptores de acceso de propiedad, un nombre diferente de "returnValue").

  • Use el atributo ReturnValueNameAttribute para cambiar el nombre del valor devuelto, como se muestra aquí:

    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
    

Nota Si cambia el nombre del valor devuelto y el nuevo nombre entra en conflicto con el nombre de otro parámetro, obtendrá el error WME1091.

El código JavaScript puede tener acceso a los parámetros de salida de un método por nombre, incluido el valor devuelto. Para obtener un ejemplo, vea el atributo ReturnValueNameAttribute.

Número de error Texto del mensaje
WME1091 El método "{0}" tiene el valor devuelto denominado "{1}" que es el mismo que un nombre de parámetro. Los parámetros del método de Windows Runtime y el valor devuelto deben tener nombres únicos.
WME1092 El método "{0}" tiene un parámetro denominado "{1}" que es el mismo que el nombre del valor devuelto predeterminado. Considere la posibilidad de usar otro nombre para el parámetro o usar System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute para especificar explícitamente el nombre del valor devuelto.

Nota El nombre predeterminado es "returnValue" para descriptores de acceso de propiedad y "valor" para todos los demás métodos.