Diagnosticar condiciones de error en componentes de Windows en tiempo de ejecución
En este artículo se proporciona información adicional sobre las restricciones en los componentes de Windows en tiempo de ejecución escritos con código administrado. Expande la información que se proporciona en los mensajes de error de Winmdexp.exe (Herramienta de exportación de metadatos de Windows en tiempo de ejecución) y complementa la información sobre restricciones que se proporciona en Crear componentes de Windows en tiempo de ejecución en C# y Visual Basic.
En este artículo no se tratan todos los errores. Los errores que se analizan aquí se agrupan por categoría general y cada categoría incluye una tabla de mensajes de error asociados. Busque el texto del mensaje (omitiendo los valores específicos de los marcadores) o el número de mensaje. Si no encuentras la información que necesitas, ayúdanos a mejorar la documentación utilizando el botón de comentarios situado al final de este artículo. Incluye el mensaje de error. O bien, puedes registrar el error en el sitio web Microsoft Connect.
Este artículo contiene las siguientes secciones:
Al implementar el modelo asincrónico, el mensaje de error proporciona el tipo incorrecto
Referencias que faltan a mscorlib.dll o System.Runtime.dll
No se permite la sobrecarga de operadores
Los constructores de una clase tienen el mismo número de parámetros
Se debe especificar un valor predeterminado para las sobrecargas que tienen el mismo número de parámetros
Errores de espacio de nombres y nombres no válidos para el archivo de salida
Exportar tipos que no son tipos válidos de Windows en tiempo de ejecución
Estructuras que contienen campos de tipos no permitidos
Restricciones en las matrices en firmas de miembro
Los parámetros de matriz deben especificar si el contenido de la matriz se puede leer o escribir
Miembro con un parámetro con el nombre "value"
El mensaje de error para implementar una interfaz asincrónica proporciona el tipo incorrecto
Los componentes administrados de Windows en tiempo de ejecución no pueden implementar las interfaces de Windows en tiempo de ejecución que representan acciones u operaciones asincrónicas (IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult> o IAsyncOperationWithProgress<TResult, TProgress>). En su lugar, .NET Framework proporciona la clase AsyncInfo para generar operaciones asincrónicas en los componentes de Windows en tiempo de ejecución. El mensaje de error que Winmdexp.exe muestra cuando intentas implementar una interfaz asincrónica hace referencia incorrectamente a esta clase por su nombre anterior, AsyncInfoFactory. .NET Framework ya no incluye la clase AsyncInfoFactory.
Número de error |
Texto del mensaje |
---|---|
WME1084 |
El tipo '{0}' implementa la interfaz asincrónica '{1}' de Windows en tiempo de ejecución. Los tipos de Windows en tiempo de ejecución no pueden implementar interfaces asincrónicas. Use la clase System.Runtime.InteropServices.WindowsRuntime.AsyncInfoFactory para generar operaciones asincrónicas para exportarlas a Windows en tiempo de ejecución. |
Referencias que faltan a mscorlib.dll o System.Runtime.dll
Este problema solo se produce cuando se utiliza Winmdexp.exe desde la línea de comandos. Recomendamos utilizar la opción /reference para incluir referencias a mscorlib.dll y System.Runtime.dll desde los ensamblados básicos de referencia de .NET Framework, que se encuentran en "%ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5" ("%ProgramFiles%\..." en un equipo de 32bits).
Número de error |
Texto del mensaje |
---|---|
WME1009 |
No se hace referencia a mscorlib.dll. Se necesita una referencia a este archivo de metadatos para que la exportación sea correcta. |
WME1090 |
No se pudo determinar el ensamblado de referencia principal. Asegúrese de que se hace referencia a mscorlib.dll y System.Runtime.dll con el modificador /reference. |
No se permite la sobrecarga de operadores
En un componente de Windows en tiempo de ejecución 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 mediante 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 de operador. Los tipos administrados no pueden exponer sobrecargas de operador en Windows en tiempo de ejecución. |
Los constructores de una clase tienen el mismo número de parámetros
En Windows en tiempo de ejecución, una clase puede tener solo un constructor con un número especificado de parámetros; por ejemplo, no se puede tener un constructor con un único parámetro de tipo String y otro con un único parámetro de tipo int (Integer en Visual Basic). La única solución es utilizar 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}' argumentos. Los tipos de Windows en tiempo de ejecución no pueden tener varios constructores con el mismo número de argumentos. |
Se debe especificar un valor predeterminado para las sobrecargas que tienen el mismo número de parámetros
En Windows en tiempo de ejecución, los métodos sobrecargados pueden tener el mismo número de parámetros solo si se especifica una sobrecarga como sobrecarga predeterminada. Consulta “Métodos sobrecargados” en Crear componentes de Windows en tiempo de ejecución en C# y Visual Basic.
Número de error |
Texto del mensaje |
---|---|
WME1059 |
Varias sobrecargas de {0} parámetros de '{1}.{2}' están representadas con Windows.Foundation.Metadata.DefaultOverloadAttribute. |
WME1085 |
Las sobrecargas {0} parámetro de {1}. {2} deben tener exactamente un método especificado como sobrecarga predeterminada representándola con Windows.Foundation.Metadata.DefaultOverloadAttribute. |
Errores de espacio de nombres y nombres no válidos para el archivo de salida
En Windows en tiempo de ejecución, 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 subespacios de nombres del nombre de archivo. Por ejemplo, si el proyecto de Visual Studio 2012 se denomina A.B (es decir, el componente de Windows en tiempo de ejecución es A.B.winmd), puede contener las 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 utilizados en tu implementación.
En el caso de A.Class3, puedes mover Clase3 a otro espacio de nombres o cambiar el nombre del componente de Windows en tiempo de ejecución a A.winmd. Aunque WME0006 es una advertencia, debes tratarla como un error. En el ejemplo anterior, el código que llama a A.B.winmd no podrá ubicar A.Class3.
En el caso de D.Class4, ningún nombre de archivo puede contener D.Class4 y las clases del espacio de nombres A.B, por lo que cambiar el nombre del componente de Windows en tiempo de ejecución no es una opción. Puedes mover D.Class4 a otro espacio de nombres, o colocarla en otro componente de Windows en tiempo de ejecución.
El sistema de archivos no puede distinguir entre mayúsculas y minúsculas, por lo que no se permiten los espacios de nombres que se diferencian en la grafía (WME1067).
Tu componente debe contener al menos un tipo public sealed (Public NotInheritable en Visual Basic). De lo contrario, obtendrás WME1042 o WME1043, en función de que el componente contenga tipos privados.
Un tipo de un componente de Windows en tiempo de ejecución no puede tener un nombre que sea igual que un espacio de nombres (WME1068).
Advertencia
Si llamas a Winmdexp.exe directamente y no utilizas la opción /out para especificar un nombre para tu componente de Windows en tiempo de ejecución, Winmdexp.exe intenta generar un nombre que incluya todos los espacios de nombres del componente. Un cambio de nombre de los espacios de nombres puede suponer el cambio del nombre de tu 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 en un subespacio de nombres del espacio de nombres que implica 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 común más pequeño 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 esté dentro de un espacio de nombres. |
WME1043 |
El módulo de entrada debe contener al menos un tipo público que esté dentro de un espacio de nombres. Los únicos tipos encontrados en espacios de nombres son privados. |
WME1044 |
Un tipo público tiene el espacio de nombres ('{1}') que no comparte un prefijo común con otros espacios de nombres ('{0}'). Todos los tipos de un archivo de metadatos de Windows deben existir en un subespacio de nombres del espacio de nombres que implica el nombre de archivo. |
WME1067 |
Los nombres de espacios de nombres no pueden diferenciarse solo por el uso de mayúsculas y minúsculas: '{0}', '{1}'. |
WME1068 |
El tipo '{0}' no puede tener el mismo nombre que el espacio de nombres '{1}'. |
Exportar tipos que no son tipos de Windows en tiempo de ejecución válidos
La interfaz pública de tu componente debe exponer solo tipos de Windows en tiempo de ejecución. Sin embargo, .NET Framework proporciona asignaciones a un número de tipos utilizados frecuentemente que son ligeramente diferentes en .NET Framework y Windows en tiempo de ejecución. Esto permite al desarrollador de .NET Framework trabajar con tipos conocidos en lugar de tener que aprender nuevos. Puedes usar estos tipos de .NET Framework asignados en la interfaz pública de tu componente. Consulta “Declarar tipos en componentes de Windows en tiempo de ejecución” y “Pasar tipos de Windows en tiempo de ejecución a código administrado” en Crear componentes de Windows en tiempo de ejecución en C# y Visual Basic y Asignaciones de tipos de Windows Runtime en .NET Framework.
Muchas de estas asignaciones son interfaces. Por ejemplo, IList<T> se asigna a la interfaz IVector<T>de Windows en tiempo de ejecución. Si utilizas List<string> (List(Of String) en Visual Basic) en lugar de IList<string> como tipo de parámetro, Winmdexp.exe proporciona una lista de alternativas que incluye todas las interfaces asignadas implementadas por List<T>. Si utilizas tipos genéricos anidados, por ejemplo List<Dictionary<int, string>> (List(Of Dictionary(Of Integer, String)) en Visual Basic), Winmdexp.exe ofrecerá opciones para cada nivel de anidamiento. Estas listas pueden llegar a ser muy largas.
Normalmente, la mejor opción es la interfaz más próxima al tipo. Por ejemplo, para Dictionary<int, string>, es muy probable que la mejor opción sea IDictionary<int, string>.
Importante
JavaScript utiliza la interfaz que aparece en primer lugar en la lista de interfaces que un tipo administrado implementa. Por ejemplo, si devuelves Dictionary<int, string> al código de JavaScript, aparecerá como IDictionary<int, string> con independencia de la interfaz que especifiques como tipo de valor devuelto. Esto significa que si la primera interfaz no incluye un miembro que aparece en interfaces posteriores, dicho miembro no es visible para JavaScript.
Advertencia
No utilices las interfaces no genéricas IList y IEnumerable si JavaScript va a utilizar tu componente. Estas interfaces se asignan a IBindableVector e IBindableIterator, respectivamente. Admiten el enlace de controles de XAML y no son visibles 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 invocar”.
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 en tiempo de ejecución. |
WME1038 |
El método '{0}' tiene un parámetro de tipo '{1}' en la firma. Aunque este tipo no es un tipo válido de Windows en tiempo de ejecución, implementa interfaces que son tipos válidos de Windows en tiempo de ejecución. Considere cambiar la firma del método para que use alguno de los siguientes tipos: '{2}'. |
WME1039 |
El método '{0}' tiene un parámetro de tipo '{1}' en la firma. Aunque este tipo genérico no es un tipo válido de Windows en tiempo de ejecución, el tipo o sus parámetros genéricos implementan interfaces que son tipos válidos de Windows en tiempo de ejecución. {2}
Nota
En el caso de {2}, Winmdexp.exe anexa una lista de alternativas, como “Considere cambiar el tipo 'System.Collections.Generic.List<T>' de la firma del método a alguno de siguientes tipos: '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 la firma. En lugar de usar un tipo Task administrado, use Windows.Foundation.IAsyncAction, Windows.Foundation.IAsyncOperation o alguna de las interfaces asincrónicas de Windows en tiempo de ejecución. El patrón await estándar de .NET se aplica también a estas interfaces. Vea 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 en tiempo de ejecución. |
Estructuras que contienen campos de tipos no permitidos
En Windows en tiempo de ejecución, una estructura puede contener solo campos y solo las estructuras pueden contener campos. Esos campos deben ser públicos. Entro los tipos de campo válidos se incluyen enumeraciones, estructuras y tipos primitivos.
Número de error |
Texto del mensaje |
---|---|
WME1060 |
La estructura '{0}' tiene el campo '{1}' de tipo '{2}'. '{2}'no es un tipo de campo válido de Windows en tiempo de ejecución. Todos los campos de una estructura de Windows en tiempo de ejecución solo pueden ser UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Boolean, String, Enum, o una estructura en sí mismos. |
Restricciones en las matrices en firmas de miembro
En Windows en tiempo de ejecución, las matrices en firmas de miembro deben ser unidimensionales con un límite inferior de 0 (cero). Los tipos de matrices anidadas como myArray[][] (myArray()() en Visual Basic) no están permitidos.
Nota
Esta restricción no se aplica a las matrices que utilices internamente en tu implementación.
Número de error |
Texto del mensaje |
---|---|
WME1034 |
El método '{0}' tiene una matriz de tipo '{1}' con un límite inferior distinto de cero en la firma. Las matrices de firmas de métodos de Windows en tiempo de ejecución deben tener un límite inferior de cero. |
WME1035 |
El método '{0}' tiene una matriz multidimensional de tipo '{1}' en la firma. Las matrices de firmas de método de métodos de Windows en tiempo de ejecución deben ser unidimensionales. |
WME1036 |
El método '{0}' tiene una matriz anidada de tipo '{1}' en la firma. Las matrices de firmas de métodos de Windows en tiempo de ejecución no pueden ser anidadas. |
Los parámetros de matriz deben especificar si el contenido de la matriz se puede leer o escribir
En Windows en tiempo de ejecución, los parámetros deben ser de solo lectura o de solo escritura. Los parámetros no se pueden marcar 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 una matriz son de solo lectura o de solo escritura. La dirección está clara en el caso de parámetros out (parámetro ByRef con el atributo OutAttribute en Visual Basic), pero los parámetros de matriz que se pasan por valor (ByVal en Visual Basic) se deben marcar. Consulta Pasar matrices a un componente de Windows en tiempo de ejecución.
Número de error |
Texto del mensaje |
---|---|
WME1101 |
El método '{0}' tiene el parámetro '{1}', que es una matriz y tiene tanto {2} como {3}. En Windows en tiempo de ejecución, el contenido de los parámetros de matriz debe poderse leer o escribir. Quite uno de los atributos de '{1}'. |
WME1102 |
El método '{0}' tiene un parámetro de salida '{1}' que es una matriz, pero tiene {2}. En Windows en tiempo de ejecución, 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 tiene System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. En Windows en tiempo de ejecución, los parámetros de matriz deben tener {2} o {3}. Quite estos atributos o, si es necesario, reemplácelos por el atributo apropiado de Windows en tiempo de ejecución. |
WME1104 |
El método '{0}' tiene el parámetro '{1}', que no es una matriz y tiene {2} o {3}. Windows en tiempo de ejecución no admite marcar parámetros que no sean matrices con {2} o {3}. |
WME1105 |
El método '{0}' tiene el parámetro '{1}' con System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Windows en tiempo de ejecución no admite marcar parámetros con System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Considere 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 System.Runtime.InteropServices.InAttribute o System.Runtime.InteropServices.OutAttribute. Windows en tiempo de ejecución solo admite marcar los parámetros ByRef con System.Runtime.InteropServices.OutAttribute y no admite otros usos de estos atributos. |
WME1106 |
El método '{0}' tiene el parámetro '{1}' que es una matriz. En Windows en tiempo de ejecución, el contenido de los parámetros de matriz debe poderse leer o escribir. Aplique {2} o {3} a '{1}'. |
Miembro con un parámetro con el nombre “value”
En Windows en tiempo de ejecución, los valores devueltos se consideran parámetros de salida y los nombres de los parámetros deben ser únicos. De forma predeterminada, Winmdexp.exe asigna al valor devuelto el nombre “value”. Si tu método tiene un parámetro con el nombre “value”, obtendrás el error WME1092. Esto se puede corregir de dos maneras:
Asigna a tu parámetro un nombre distinto de “value” (en los descriptores de acceso de propiedad, un nombre distinto de “returnValue”).
Utiliza 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 cambias el nombre del valor devuelto y el nuevo nombre está en conflicto con el nombre de otro parámetro, obtendrás el error WME1091.
El código de JavaScript puede tener acceso a los parámetros de salida de un método por nombre, incluido el valor devuelto. Para obtener un ejemplo, consulta el atributo ReturnValueNameAttribute.
Número de error |
Texto del mensaje |
---|---|
WME1091 |
El método '{0}' tiene el valor devuelto con el nombre '{1}', que es igual que un nombre de parámetro. Los parámetros de método de Windows en tiempo de ejecución y el valor devuelto deben tener nombres únicos. |
WME1092 |
El método '{0}' tiene un parámetro con el nombre '{1}' que es igual que el nombre de valor devuelto predeterminado. Considere el uso de otro nombre para el parámetro en su lugar o System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute para especificar de forma explícita el nombre del valor devuelto.
Nota
El nombre predeterminado es “returnValue” para los descriptores de acceso de propiedad y “value” para todos los demás métodos.
|
Vea también
Referencia
Winmdexp.exe (Herramienta de exportación de metadatos de Windows en tiempo de ejecución)
Conceptos
Crear componentes de Windows en tiempo de ejecución en C# y Visual Basic