Migración de un proyecto de Windows Runtime 8.x a un proyecto de UWPPorting a Windows Runtime 8.x project to a UWP project

Tienes dos opciones cuando empieza el proceso de migración.You have two options when you begin the porting process. Una es editar una copia de los archivos de proyecto existentes, entre los que se incluye el manifiesto del paquete de la aplicación (para esta opción, consulta la información sobre cómo actualizar los archivos de proyecto en Migrar aplicaciones a la Plataforma universal de Windows (UWP)).One is to edit a copy of your existing project files, including the app package manifest (for that option, see the info about updating your project files in Migrate apps to the Universal Windows Platform (UWP)). La otra opción es crear un nuevo proyecto de Windows 10 en Visual Studio y copiar los archivos en él.The other option is to create a new Windows 10 project in Visual Studio and copy your files into it. En la primera sección de este tema se describe esa segunda opción, pero el resto del tema contiene información adicional aplicable a ambas opciones.The first section in this topic describes that second option, but the rest of the topic has additional info applicable to both options. También puedes mantener tu nuevo proyecto de Windows 10 en la misma solución que tus proyectos existentes y compartir archivos de código fuente mediante un proyecto compartido.You can also choose to keep your new Windows 10 project in the same solution as your existing projects and share source code files using a shared project. También puedes mantener el nuevo proyecto en una solución específica y compartir archivos de código fuente mediante la característica de archivos vinculados de Visual Studio.Or, you can keep the new project in a solution of its own and share source code files using the linked files feature in Visual Studio.

Crear el proyecto y copiar archivos en élCreate the project and copy files to it

Estos pasos se centran en la opción de crear un nuevo proyecto de Windows 10 en Visual Studio y copiar los archivos en él.These steps focus on the option to create a new Windows 10 project in Visual Studio and copy your files into it. Algunos de los aspectos específicos relacionados con el número de proyectos que creas y qué archivos copias, dependerán de los factores y decisiones descritos en Si tienes una aplicación Universal 8.1 y las secciones siguientes.Some of the specifics around how many projects you create, and which files you copy over, will depend on the factors and decisions described in If you have a Universal 8.1 app and the sections that follow it. Estos pasos suponen el caso más simple.These steps assume the simplest case.

  1. Inicia Microsoft Visual Studio 2015 y crea un nuevo proyecto de aplicación vacía (universal de Windows).Launch Microsoft Visual Studio 2015 and create a new Blank Application (Windows Universal) project. Para obtener más información, consulte JumpStart your Windows Runtime 8. x App Using Templates (C#, C++, Visual Basic).For more info, see Jumpstart your Windows Runtime 8.x app using templates (C#, C++, Visual Basic). Tu nuevo proyecto crea un paquete de la aplicación (un archivo appx) que se ejecutará en todas las familias de dispositivos.Your new project builds an app package (an appx file) that will run on all device families.
  2. En tu proyecto de aplicación Universal 8.1, identifica todos los archivos de código fuente y los archivos de activos visuales que quieres reutilizar.In your Universal 8.1 app project, identify all the source code files and visual asset files that you want to reuse. Con el Explorador de archivos, copia los modelos de datos, los modelos de vista, los recursos visuales, los diccionarios de recursos, la estructura de carpetas y cualquier otro elemento que quieras reutilizar en tu nuevo proyecto.Using File Explorer, copy data models, view models, visual assets, Resource Dictionaries, folder structure, and anything else that you wish to re-use, to your new project. Copia o crea subcarpetas en el disco según sea necesario.Copy or create sub-folders on disk as necessary.
  3. Copia vistas (por ejemplo, MainPage.xaml y MainPage.xaml.cs) en el nuevo proyecto también.Copy views (for example, MainPage.xaml and MainPage.xaml.cs) into the new project, too. De nuevo, crea nuevas subcarpetas según sea necesario y quita las vistas existentes del proyecto.Again, create new sub-folders as necessary, and remove the existing views from the project. Pero antes de sobrescribir o quitar una vista que Visual Studio ha generado, conserva una copia ya que puede resultar útil consultarla más adelante.But, before you over-write or remove a view that Visual Studio generated, keep a copy because it may be useful to refer to it later. La primera fase de migración de una aplicación Universal 8.1 se centra en que tenga un buen aspecto y funcione correctamente en una familia de dispositivos.The first phase of porting a Universal 8.1 app focuses on getting it to look good and work well on one device family. Más adelante, desviarás tu atención a asegurarte de que las vistas de adaptan correctamente a todos los factores de forma y, opcionalmente, a agregar código adaptable para obtener el máximo partido de una familia de dispositivos en particular.Later, you'll turn your attention to making sure the views adapt themselves well to all form factors, and optionally to adding any adaptive code to get the most from a particular device family.
  4. En el Explorador de soluciones, asegúrate de que Mostrar todos los archivos esté activado.In Solution Explorer, make sure Show All Files is toggled on. Selecciona los archivos que has copiado, haz clic con el botón secundario en ellos y haz clic en Incluir en el proyecto.Select the files that you copied, right-click them, and click Include In Project. Esto incluirá automáticamente sus carpetas contenedoras.This will automatically include their containing folders. Entonces puedes desactivar Mostrar todos los archivos si quieres.You can then toggle Show All Files off if you like. Un flujo de trabajo alternativo, si lo prefieres, es usar el comando Agregar elemento existente, después de crear las subcarpetas necesarias en el Explorador de soluciones de Visual Studio.An alternative workflow, if you prefer, is to use the Add Existing Item command, having created any necessary sub-folders in the Visual Studio Solution Explorer. Vuelve a comprobar que los recursos visuales tienen la opción Acción de compilación establecida en Contenido y la opción Copiar en el directorio de resultados establecida en No copiar.Double-check that your visual assets have Build Action set to Content and Copy to Output Directory set to Do not copy.
  5. Es probable que se vean algunos errores de compilación en esta fase.You are likely to see some build errors at this stage. Pero si sabes lo que necesitas cambiar, puedes usar el comando Buscar y reemplazar de Visual Studio para realizar cambios masivos en tu código fuente; en el editor de código imperativo de Visual Studio, usa los comandos Resolve y Organizar instrucciones Using del menú contextual para realizar cambios más específicos.But, if you know what you need to change, then you can use Visual Studio's Find and Replace command to make bulk changes to your source code; and in the imperative code editor in Visual Studio, use the Resolve and Organize Usings commands on the context menu for more targeted changes.

Maximización de la reutilización de código y marcadoMaximizing markup and code reuse

Encontrarás que refactorizar un poco o agregar código adaptable (lo cual se explica a continuación), te permitirá maximizar el marcado y el código que funciona en todas las familias de dispositivo.You will find that refactoring a little, and/or adding adaptive code (which is explained below), will allow you to maximize the markup and code that works across all device families. A continuación se indican más detalles.Here are more details.

  • Los archivos que son comunes a todas las familias de dispositivo no necesitan ninguna consideración especial.Files that are common to all device families need no special consideration. Esos archivos serán usados por la aplicación en todas las familias de dispositivos en las que se ejecuta.Those files will be used by the app on all the device families that it runs on. Esto incluye los archivos de marcado XAML, los archivos de código fuente imperativo y los archivos de recursos.This includes XAML markup files, imperative source code files, and asset files.
  • Es posible que tu aplicación detecte la familia de dispositivos en la que se está ejecutando y navegar a una vista que se ha diseñado específicamente para esa familia de dispositivos.It is possible for your app to detect the device family that it is running on and navigate to a view that has been designed specifically for that device family. Para obtener más información, consulta Detección de la plataforma en la que se está ejecutando la aplicación.For more details, see Detecting the platform your app is running on.
  • Una técnica similar que puede resultar útil si no existe otra alternativa es proporcionar a un archivo de marcado o archivo ResourceDictionary (o la carpeta que contiene el archivo) un nombre especial que se carga automáticamente en tiempo de ejecución solo cuando la aplicación se ejecuta en una familia de dispositivos en particular.A similar technique that you may find useful if there is no alternative is give a markup file or ResourceDictionary file (or the folder that contains the file) a special name such that it is automatically loaded at runtime only when your app runs on a particular device family. Esta técnica se ilustra en el caso práctico Bookstore1.This technique is illustrated in the Bookstore1 case study.
  • Debes poder eliminar muchas de las directivas de compilación condicional del código fuente de la aplicación Universal 8.1 si solo necesitas compatibilidad con Windows 10.You should be able to remove a lot of the conditional compilation directives in your Universal 8.1 app's source code if you only need to support Windows 10. Vea compilación condicional y código adaptable en este tema.See Conditional compilation and adaptive code in this topic.
  • Para usar características que no están disponibles en todas las familias de dispositivos (por ejemplo, impresoras, escáneres o el botón de la cámara) puedes escribir código adaptable.To use features that are not available on all device families (for example, printers, scanners, or the camera button), you can write adaptive code. Vea el tercer ejemplo de la compilación condicional y el código adaptable de este tema.See the third example in Conditional compilation and adaptive code in this topic.
  • Si quieres disponer de compatibilidad con Windows 8.1, Windows Phone 8.1 y Windows 10, puedes mantener tres proyectos en la misma solución y compartir código con un proyecto compartido.If you want to support Windows 8.1, Windows Phone 8.1, and Windows 10, then you can keep three projects in the same solution and share code with a Shared project. Como alternativa, puedes compartir archivos de código fuente entre proyectos.Alternatively, you can share source code files between projects. Pasos a seguir: en Visual Studio, haz clic con el botón derecho en el proyecto en Explorador de soluciones, selecciona Agregar elemento existente, selecciona los archivos para compartir y haz clic en Agregar como vínculo.Here's how: in Visual Studio, right-click the project in Solution Explorer, select Add Existing Item, select the files to share, and then click Add As Link. Almacena tus archivos de código fuente en una carpeta común en el sistema de archivos donde puedan verlos los proyectos vinculados a ellos.Store your source code files in a common folder on the file system where the projects that link to them can see them. Y no te olvides de agregarlos al control de origen.And don't forget to add them to source control.
  • Para reutilizarlo en el nivel binario, en lugar de en el nivel de código fuente, vea crear Windows Runtime componentes en C# y Visual Basic.For reuse at the binary level, rather than the source code level, see Creating Windows Runtime components in C# and Visual Basic. También hay bibliotecas de clases portables que admiten el subconjunto de las API de .NET que están disponibles en .NET Framework para aplicaciones Windows 8.1, Windows Phone 8.1 y Windows 10 (núcleo de .NET) y el conjunto completo de .NET Framework.There are also Portable Class Libraries, which support the subset of .NET APIs that are available in the .NET Framework for Windows 8.1, Windows Phone 8.1, and Windows 10 apps (.NET Core), and the full .NET Framework. Los conjuntos de bibliotecas de clases portables tienen compatibilidad binaria con estas plataformas.Portable Class Library assemblies are binary compatible with all these platforms. Usa Visual Studio para crear un proyecto destinado a una biblioteca de clases portable.Use Visual Studio to create a project that targets a Portable Class Library. Consulta Desarrollo multiplataforma con la biblioteca de clases portable.See Cross-Platform Development with the Portable Class Library.

SDK de extensionesExtension SDKs

La mayoría de las API de Windows Runtime a las que tu aplicación Universal 8.1 ya llama se implementan en el conjunto de API denominado "familia de dispositivos universales".Most of the Windows Runtime APIs your Universal 8.1 app already calls are implemented in the set of APIs known as the universal device family. Pero algunas se implementan en los SDK de extensión y Visual Studio solo reconoce las API que están implementadas por la familia de dispositivos de destino de la aplicación o por los SDK de extensión a los que has hecho referencia.But, some are implemented in extension SDKs, and Visual Studio only recognizes APIs that are implemented by your app's target device family or by any extension SDKs that you have referenced.

Si se producen errores de compilación sobre espacios de nombres o tipos o miembros no encontrados, es probable que esta sea la causa.If you get compile errors about namespaces or types or members that could not be found, then this is likely to be the cause. Abre el tema de las API en la documentación de referencia de la API y navega hasta la sección Requisitos, donde podrás consultar cuál es la familia de dispositivos de la implementación.Open the API's topic in the API reference documentation and navigate to the Requirements section: that will tell you what the implementing device family is. Si esa no es la familia de dispositivos de destino, para que la API esté disponible para el proyecto, necesitarás una referencia al SDK de extensión de esa familia de dispositivos.If that's not your target device family, then to make the API available to your project, you will need a reference to the extension SDK for that device family.

Haz clic en Proyecto > Agregar referencia > Windows Universal > Extensiones y selecciona el SDK de extensión apropiado.Click Project > Add Reference > Windows Universal > Extensions and select the appropriate extension SDK. Por ejemplo, si las API a las que quieres llamar solo están disponibles en la familia de dispositivos móviles y se introdujeron en la versión 10.0.x.y, selecciona Extensiones de Windows Mobile para UWP.For example, if the APIs you want to call are available only in the mobile device family, and they were introduced in version 10.0.x.y, then select Windows Mobile Extensions for the UWP.

Ello agregará la siguiente referencia al archivo de proyecto:That will add the following reference to your project file:

<ItemGroup>
    <SDKReference Include="WindowsMobile, Version=10.0.x.y">
        <Name>Windows Mobile Extensions for the UWP</Name>
    </SDKReference>
</ItemGroup>

El nombre y el número de versión coinciden con las carpetas de la ubicación de instalación del SDK.The name and version number match the folders in the installed location of your SDK. Por ejemplo, la información anterior coincide con este nombre de carpeta:For example, the above information matches this folder name:

\Program Files (x86)\Windows Kits\10\Extension SDKs\WindowsMobile\10.0.x.y

A menos que la aplicación esté destinada a la familia de dispositivos que implementa la API, tendrás que usar la clase ApiInformation para probar la presencia de la API antes de llamarla (esto se denomina "código adaptable").Unless your app targets the device family that implements the API, you'll need to use the ApiInformation class to test for the presence of the API before you call it (this is called adaptive code). A continuación, se evaluará esta condición donde se ejecute la aplicación, pero solo se evaluará en true en dispositivos en los que la API está presente y, por tanto, está disponible para ser llamada.This condition will then be evaluated wherever your app runs, but it will only evaluate to true on devices where the API is present and therefore available to call. Usa únicamente los SDK de extensión y el código adaptable después de comprobar primero si existe una API universal.Only use extension SDKs and adaptive code after first checking whether a universal API exists. En la sección siguiente se proporcionan algunos ejemplos.Some examples are given in the section below.

Consulta también Manifiesto del paquete de la aplicación.Also, see App package manifest.

Compilación condicional y código adaptableConditional compilation and adaptive code

Si usas la compilación condicional (con directivas de preprocesador C#) para que los archivos de código funcionen en Windows 8.1 y Windows Phone 8.1, ahora puedes revisar esa compilación condicional a la luz del trabajo de convergencia realizado en Windows 10.If you're using conditional compilation (with C# preprocessor directives) so that your code files work on both Windows 8.1 and Windows Phone 8.1, then you can now review that conditional compilation in light of the convergence work done in Windows 10. Convergencia significa que, en la aplicación de Windows 10, algunas condiciones se pueden quitar por completo.Convergence means that, in your Windows 10 app, some conditions can be removed altogether. Otras cambian a comprobaciones en tiempo de ejecución, como se muestra en los siguientes ejemplos.Others change to run-time checks, as demonstrated in the examples below.

Nota:    Si desea admitir Windows 8.1, Windows Phone 8,1 y Windows 10 en un solo archivo de código, también puede hacerlo.Note   If you want to support Windows 8.1, Windows Phone 8.1, and Windows 10 in a single code file, then you can do that too. Si busca en el proyecto de Windows 10 en las páginas de propiedades del proyecto, verá que el proyecto define WINDOWS _ UAP como un símbolo de compilación condicional.If you look in your Windows 10 project at the project properties pages, you'll see that the project defines WINDOWS_UAP as a conditional compilation symbol. Por lo tanto, puede usarlo en combinación con la aplicación de WINDOWS _ y la aplicación de Windows _ Phone _ .So, you can use that in combination with WINDOWS_APP and WINDOWS_PHONE_APP. En estos ejemplos se muestra el caso más simple de eliminación de la compilación condicional de una aplicación Universal 8.1 de sustitución del código equivalente para una aplicación de Windows 10.These examples show the simpler case of removing the conditional compilation from a Universal 8.1 app and substituting the equivalent code for a Windows 10 app.

Este primer ejemplo muestra el patrón de uso de la API PickSingleFileAsync (que se aplica únicamente a Windows 8.1) y la API PickSingleFileAndContinue (que se aplica únicamente a Windows Phone 8.1).This first example shows the usage pattern for the PickSingleFileAsync API (which applies only to Windows 8.1) and the PickSingleFileAndContinue API (which applies only to Windows Phone 8.1).

#if WINDOWS_APP
    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync
#else
    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAndContinue
#endif // WINDOWS_APP

Windows 10 converge en la API PickSingleFileAsync, por lo que el código se simplifica en el siguiente:Windows 10 converges on the PickSingleFileAsync API, so your code simplifies to this:

    // Use Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync

En este ejemplo, se controla el botón Atrás de hardware, pero solo en Windows Phone.In this example, we handle the hardware back button—but only on Windows Phone.

#if WINDOWS_PHONE_APP
        Windows.Phone.UI.Input.HardwareButtons.BackPressed += this.HardwareButtons_BackPressed;
#endif // WINDOWS_PHONE_APP

...

#if WINDOWS_PHONE_APP
    void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
    {
        // Handle the event.
    }
#endif // WINDOWS_PHONE_APP

En Windows 10, el evento de botón Atrás es un concepto universal.In Windows 10, the back button event is a universal concept. Los botones Atrás implementados en hardware o en software generarán el evento BackRequested, por lo que ese es el que hay que controlar.Back buttons implemented in hardware or in software will all raise the BackRequested event, so that's the one to handle.

    Windows.UI.Core.SystemNavigationManager.GetForCurrentView().BackRequested +=
        this.ViewModelLocator_BackRequested;

...

private void ViewModelLocator_BackRequested(object sender, Windows.UI.Core.BackRequestedEventArgs e)
{
    // Handle the event.
}

Este ejemplo final es similar al anterior.This final example is similar to the previous one. Aquí tratamos el botón de la cámara de hardware, pero solo en el código compilado en el paquete de la aplicación de Windows Phone.Here, we handle the hardware camera button—but again, only in the code compiled into the Windows Phone app package.

#if WINDOWS_PHONE_APP
    Windows.Phone.UI.Input.HardwareButtons.CameraPressed += this.HardwareButtons_CameraPressed;
#endif // WINDOWS_PHONE_APP

...

#if WINDOWS_PHONE_APP
void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
    // Handle the event.
}
#endif // WINDOWS_PHONE_APP

En Windows 10, el botón de la cámara de hardware es un concepto específico de la familia de dispositivos móviles.In Windows 10, the hardware camera button is a concept particular to the mobile device family. Debido a que se ejecutará un paquete de la aplicación en todos los dispositivos, cambiamos nuestra condición de tiempo de compilación a una condición de tiempo de ejecución mediante el uso de código adaptable.Because one app package will be running on all devices, we change our compile-time condition into a run-time condition using what is known as adaptive code. Para ello, usamos la clase ApiInformation para consultar en tiempo de ejecución la presencia de la clase HardwareButtons.To do that, we use the ApiInformation class to query at run-time for the presence of the HardwareButtons class. HardwareButtons se define en el SDK de la extensión móvil, por lo que tendremos que agregar una referencia a ese SDK a nuestro proyecto para poder compilar este código.HardwareButtons is defined in the mobile extension SDK, so we'll need to add a reference to that SDK to our project for this code to compile. No obstante, ten en cuenta que el controlador solo se ejecutará en un dispositivo que implementa los tipos definidos en el SDK de extensión móvil y que esa es la familia de dispositivos móviles.Note, though, that the handler will only be executed on a device that implements the types defined in the mobile extension SDK, and that's the mobile device family. Por lo tanto, este código es moralmente equivalente al código Universal 8.1 en que procura usar únicamente características que están presentes, aunque lo consiga de un modo distinto.So, this code is morally equivalent to the Universal 8.1 code in that it is careful only to use features that are present, although it achieves that in a different way.

    // Note: Cache the value instead of querying it more than once.
    bool isHardwareButtonsAPIPresent = Windows.Foundation.Metadata.ApiInformation.IsTypePresent
        ("Windows.Phone.UI.Input.HardwareButtons");

    if (isHardwareButtonsAPIPresent)
    {
        Windows.Phone.UI.Input.HardwareButtons.CameraPressed +=
            this.HardwareButtons_CameraPressed;
    }

    ...

private void HardwareButtons_CameraPressed(object sender, Windows.Phone.UI.Input.CameraEventArgs e)
{
    // Handle the event.
}

Consulta también Detección de la plataforma en la que se está ejecutando la aplicación.Also, see Detecting the platform your app is running on.

Manifiesto del paquete de la aplicaciónApp package manifest

En el tema Qué ha cambiado en Windows 10 se ofrece una lista con los cambios en la referencia del esquema de manifiesto del paquete para Windows 10, entre los que se incluyen los elementos que se han agregado, quitado y cambiado.The What's changed in Windows 10 topic lists changes to the package manifest schema reference for Windows 10, including elements that have been added, removed, and changed. Para obtener información de referencia sobre todos los elementos, atributos y tipos del esquema, consulta Jerarquía de elemento.For reference info on all elements, attributes, and types in the schema, see Element Hierarchy. Si va a migrar una aplicación de la tienda de Windows Phone, o si la aplicación es una actualización de una aplicación de la tienda de Windows Phone, asegúrese de que el elemento PM: PhoneIdentity coincide con lo que hay en el manifiesto de la aplicación de la aplicación anterior (Use los mismos GUID que el almacén asignó a la aplicación).If you're porting a Windows Phone Store app, or if your app is an update to an app from the Windows Phone Store, ensure that the pm:PhoneIdentity element matches what's in the app manifest of your previous app (use the same GUIDs that were assigned to the app by the Store). Esto garantizará que los usuarios de la aplicación que están actualizando a Windows 10 recibirán la nueva aplicación como una actualización, no un duplicado.This will ensure that users of your app who are upgrading to Windows 10 will receive your new app as an update, not a duplicate. Consulte el tema de referencia PM: PhoneIdentity para obtener más detalles.See the pm:PhoneIdentity reference topic for more details.

La configuración del proyecto (incluidas las referencias de SDK de extensión) determina el área de superficie de API que tu aplicación puede llamar.The settings in your project (including any extension SDKs references) determine the API surface area that your app can call. Pero el manifiesto del paquete de la aplicación es lo que determina el conjunto real de dispositivos en los que los clientes pueden instalar la aplicación desde la Tienda.But, your app package manifest is what determines the actual set of devices that your customers can install your app onto from the Store. Para obtener más información, vea los ejemplos de TargetDeviceFamily.For more info, see examples in TargetDeviceFamily.

Puedes editar el manifiesto del paquete de la aplicación para establecer varias declaraciones, capacidades y otras opciones de configuración que algunas funciones necesitan.You can edit the app package manifest to set various declarations, capabilities, and other settings that some features need. Puedes usar el editor de manifiestos del paquete de aplicaciones de Visual Studio para editarlo.You can use the Visual Studio app package manifest editor to edit it. Si el Explorador de soluciones no se muestra, selecciónalo en el menú Ver.If the Solution Explorer is not shown, choose it from the View menu. Haga doble clic en Package.appxmanifest.Double-click Package.appxmanifest. Esta acción abre la ventana del editor de manifiestos.This opens the manifest editor window. Selecciona la pestaña apropiada para realizar cambios y luego guarda.Select the appropriate tab to make changes and then save.

El siguiente tema es Solución de problemas.The next topic is Troubleshooting.