Aplicación del marco de compatibilidad de paquete en Visual Studio

El marco de compatibilidad de paquetes (PSF) es un proyecto de código abierto que permite aplicar correcciones a la aplicación de escritorio existente. PSF permite que una aplicación se ejecute en un formato empaquetado sin modificar el código. La plataforma de compatibilidad de paquete te ayuda a que la aplicación siga las prácticas recomendadas del entorno de tiempo de ejecución moderno.

En las secciones siguientes, exploraremos cómo crear un nuevo proyecto de Visual Studio, incluir el marco de compatibilidad de paquetes para la solución y crear correcciones en tiempo de ejecución.

Paso 1: Creación de una solución de paquete en Visual Studio

En Visual Studio, crea una nueva solución de Visual Studio, Solución en blanco. Incluye los proyectos de aplicación en la solución en blanco recién creada.

Paso 2: Adición de un proyecto de empaquetado

Si aún no tienes un Proyecto de paquete de aplicación de Windows, crea uno y agrégalo a la solución. Crea un nuevo visual C# -> Windows Universal -> Proyecto de paquete de aplicación de Windows y agrégalo a la solución recién creada.

Para obtener más información sobre el Proyecto de paquete de aplicación de Windows, consulta Empaquetado de la aplicación mediante Visual Studio.

En el Explorador de soluciones, haz clic con el botón derecho en el proyecto de empaquetado, selecciona Editar archivo de proyecto y, a continuación, agrégalo a la parte inferior del archivo del proyecto:

...
  <Target Name="PSFRemoveSourceProject" AfterTargets="ExpandProjectReferences" BeforeTargets="_ConvertItems">
    <ItemGroup>
      <FilteredNonWapProjProjectOutput Include="@(_FilteredNonWapProjProjectOutput)">
      <SourceProject Condition="'%(_FilteredNonWapProjProjectOutput.SourceProject)'=='_Runtime fix project name_'" />
      </FilteredNonWapProjProjectOutput>
      <_FilteredNonWapProjProjectOutput Remove="@(_FilteredNonWapProjProjectOutput)" />
      <_FilteredNonWapProjProjectOutput Include="@(FilteredNonWapProjProjectOutput)" />
    </ItemGroup>
  </Target>
</Project>

Paso 3: Adición del proyecto para la corrección en tiempo de ejecución

Agregue un nuevo proyecto de visual C++ -> Escritorio de Windows -> Biblioteca de vínculos dinámicos (DLL) a la solución.

A continuación, haz clic con el botón derecho en el proyecto y selecciona Propiedades.

En la página de propiedades, busca el campo Propiedades de configuración -> C/C++ -> Lenguaje -> Estándar del lenguaje C++. A continuación, selecciona Estándar ISO C++17 (/std:c++17) en el menú desplegable.

Haz clic con el botón derecho en el proyecto y, a continuación, en el menú contextual, elige la opción Administrar paquetes Nuget. Asegúrate de que la opción Origen del paquete está establecida en Todos o nuget.org.

Haz clic en el icono de configuración situado junto a ese campo.

Busca los paquetes Nuget para PSF y, a continuación, instala Microsoft.PackageSupportFramework para este proyecto.

nuget package

Paso 4: Adición de un proyecto que inicia el archivo ejecutable del iniciador de PSF

Agrega un nuevo Proyecto vacío de Visual C++ -> General -> a la solución.

Siga estos pasos:

  1. Haz clic con el botón derecho en ese proyecto y, a continuación, en el menú contextual, elige la opción Administrar paquetes Nuget. Asegúrate de que la opción Origen del paquete está establecida en Todos o nuget.org.
  2. Haz clic en el icono de configuración situado junto a ese campo.
  3. Busca los paquetes Nuget para PSF y, a continuación, instala Microsoft.PackageSupportFramework para este proyecto.

Abre las páginas de propiedades del proyecto y, en la página de configuración General, establece la propiedad Nombre de destino en PSFLauncher32 o PSFLauncher64 en función de la arquitectura de la aplicación.

Agrega una referencia de proyecto al proyecto de corrección en tiempo de ejecución de la solución.

Haz clic con el botón derecho en la referencia y, a continuación, en la ventana Propiedades, aplica estos valores.

Propiedad Valor
Copia local True
Copiar ensamblados satélite locales True
Salida de ensamblado de referencia True
Dependencias de la biblioteca de vínculos False
Vincular entradas de dependencia de biblioteca False

Paso 5: Configuración del proyecto de empaquetado

Para configurar el proyecto de empaquetado sigue estos pasos:

  1. En el proyecto de empaquetado, haz clic con el botón derecho en la carpeta Aplicaciones y, a continuación, selecciona Añadir referencia en el menú desplegable.
  2. Elige el proyecto de iniciador de PSF y el proyecto de aplicación de escritorio, después, selecciona el botón Aceptar.
  3. Seleccione el Iniciador de PSF y el proyecto de Aplicación de escritorio y haz clic en el botón Aceptar. Si el código fuente de la aplicación no está disponible, selecciona solo el proyecto de Iniciador de PSF.
  4. En el nodo Aplicaciones, haz clic con el botón derecho en la aplicación Iniciador de PSF y, a continuación, elige Establecer como punto de entrada.

Agrega un archivo denominado config.json al proyecto de empaquetado y, a continuación, copia y pega el siguiente texto json en el archivo. Establece la propiedad Package Action en Contenido.

{
    "applications": [
        {
            "id": "",
            "executable": "",
            "workingDirectory": ""
        }
    ],
    "processes": [
        {
            "executable": "",
            "fixups": [
                {
                    "dll": "",
                    "config": {
                    }
                }
            ]
        }
    ]
}

Proporciona un valor para cada clave. Use esta tabla como guía.

Matriz key Value
applications id Usa el valor del atributo Id del elemento Application en el manifiesto de paquete.
applications ejecutable Ruta de acceso relativa al paquete al archivo ejecutable que deseas iniciar. En la mayoría de los casos, puedes obtener este valor del archivo de manifiesto de paquete antes de modificarlo. Es el valor del atributo Executable del elemento Application.
applications workingDirectory (Opcional) Ruta de acceso relativa al paquete que se va a usar como directorio de trabajo de la aplicación que se inicia. Si no establece este valor, el sistema operativo usa el directorio System32 como directorio de trabajo de la aplicación.
procesos ejecutable En la mayoría de los casos, este será el nombre del executable configurado anteriormente con la ruta de acceso y la extensión de archivo quitadas.
correcciones dll Ruta de acceso relativa al paquete al archivo DLL de corrección que se va a cargar.
correcciones config (Opcional) Controla cómo se comporta el archivo DLL de corrección. El formato exacto de este valor varía según la corrección, ya que cada corrección puede interpretar este "blob" como quiera.

Cuando hayas terminado, el archivo config.json tendrá un aspecto similar al siguiente.

{
  "applications": [
    {
      "id": "DesktopApplication",
      "executable": "DesktopApplication/WinFormsDesktopApplication.exe",
      "workingDirectory": "WinFormsDesktopApplication"
    }
  ],
  "processes": [
    {
      "executable": ".*App.*",
      "fixups": [ { "dll": "RuntimeFix.dll" } ]
    }
  ]
}

Nota:

Las claves applications, processes y fixups son matrices. Esto significa que puedes usar el archivo config.json para especificar más de una aplicación, proceso y archivo DLL de corrección.

Depuración de una corrección en tiempo de ejecución

En Visual Studio, pulsa F5 para iniciar el depurador. Lo primero que se inicia es la aplicación de Iniciador de PSF, que a su vez inicia la aplicación de escritorio de destino. Para depurar la aplicación de escritorio de destino, tendrás que asociarla manualmente al proceso de aplicación de escritorio seleccionando Depurar->Asociar al proceso y, a continuación, seleccionando el proceso de aplicación. Para permitir la depuración de una aplicación .NET con un archivo DLL de corrección en tiempo de ejecución nativo, selecciona tipos de código administrados y nativos (depuración en modo mixto).

Puedes establecer puntos de interrupción junto a líneas de código en el código de la aplicación de escritorio y el proyecto de corrección en tiempo de ejecución. Si no tienes el código fuente en la aplicación, podrás establecer puntos de interrupción solo junto a líneas de código en el proyecto de corrección en tiempo de ejecución.