Cómo corregir errores de permisos de escritura del sistema de archivos del marco de compatibilidad de paquetes

En este artículo se describe cómo usar el marco de compatibilidad de paquetes (PSF) para resolver un error de permiso de escritura del sistema de archivos.

Las aplicaciones de Windows redirigen directorios específicos relacionados con la aplicación a la carpeta C:\Program Files\WindowsApps. Si la aplicación intenta escribir en el contenedor de aplicaciones de Windows, se desencadena un error y se produce un error en la escritura. Puedes realizar mejoras en el paquete de aplicaciones de Windows para resolver este problema.

Investigación

En primer lugar, identifica el error y las rutas de acceso del directorio que solicita la aplicación.

Captura del error de la aplicación de Windows

El filtrado de los resultados es opcional, pero facilita la visualización de errores relacionados con la aplicación. Para filtrar los resultados, crea dos reglas de filtro. El primer filtro incluye el nombre del proceso de aplicación y el segundo incluye los resultados que no se han realizado correctamente.

  1. Descarga y extrae el Monitor de procesos de SysInternals en el directorio C:\PSF\ProcessMonitor.

  2. Abre el Explorador de Windows y ve a la carpeta de SysInternals ProcessMonitor extraída.

  3. Selecciona el archivo procmon.exe de Process Monitor de SysInternals para iniciar la aplicación.

  4. Si UAC lo solicita, selecciona .

  5. En la ventana Filtro del Monitor de procesos, selecciona Nombre del proceso en el menú desplegable del primer campo.

  6. Comprueba que aparece en el campo siguiente.

  7. En el siguiente campo, escribe el nombre del proceso de la aplicación, por ejemplo PSFSample.exe.

    Example of the Process Monitor Filter window with app name.

  8. Seleccione Agregar.

  9. En la ventana Filtro del Monitor de procesos, selecciona Resultado en el menú desplegable del primer campo.

  10. En el campo siguiente, selecciona no lo es en la lista desplegable.

  11. En el campo de texto, introduce SUCCESS.

    Example of the Process Monitor Filter window with Result.

  12. Seleccione Agregar y luego Aceptar.

  13. Inicia la aplicación de Windows, desencadena el error y cierra la aplicación de Windows.

Revisión de los registros de errores de la aplicación de Windows

Después de capturar los procesos de la aplicación de Windows, investiga los resultados para determinar si el error está relacionado con el directorio de trabajo.

Revisa los resultados del error de Process Monitor de SysInternals. Si los resultados incluyen Acceso denegado, con un detalle Acceso deseado: escritura genérica para la aplicación que tiene como destino C:\Archivos de programa\WindowsApps\...\, has identificado un error de permiso de escritura relacionado con el directorio de trabajo.

Displays the error message witnessed in the SysInternals Process Monitor for failure to write to directory.

Si identificas este error, aplica la siguiente corrección de PSF a la aplicación.

Solución

Para resolver el problema de la aplicación de Windows que no puede escribir en el contenedor de aplicaciones de Windows, sigue estos pasos:

  1. Extrae el contenido de la aplicación de Windows en un directorio de almacenamiento provisional local.
  2. Crea un archivo config.json e inserte los archivos de corrección de PSF en el directorio de aplicaciones de Windows de almacenamiento provisional.
  3. Configura el iniciador de la aplicación para que apunte al iniciador de PSF y configura el archivo config.json de PSF para redirigir el iniciador de PSF, especificando el directorio de trabajo.
  4. Actualiza el archivo AppxManifest de la aplicación de Windows.
  5. Vuelve a empaquetar y firma la aplicación de Windows.

Descarga e instalación de las herramientas necesarias

Este proceso requiere las siguientes herramientas:

  • Herramienta de cliente de NuGet
  • Marco de compatibilidad de paquete (PSF)
  • Kit de herramientas de desarrollo de software de Windows 10 (SDK de Win 10), versión más reciente
  • Process Monitor de SysInternals

Para descargar e instalar NuGet y PSF:

  1. Descarga la versión preliminar más reciente de la herramienta de cliente de NuGet y guarda nuget.exe en C:\PSF\nuget.

  2. Descarga e instala el marco de compatibilidad de paquetes con NuGet mediante la ejecución del siguiente comando desde una ventana administrativa de PowerShell:

    Set-Location "C:\PSF"
    .\nuget\nuget.exe install Microsoft.PackageSupportFramework
    

Para descargar e instalar el SDK de Windows 10:

  1. Descarga el SDK de Win 10.
  2. Ejecuta winsdksetup.exe.
  3. Seleccione Siguiente.
  4. Selecciona solo las tres características siguientes:
    • Herramientas de firma de Windows SDK para aplicaciones de escritorio
    • Windows SDK para aplicaciones de C++ para UWP
    • Localización del SDK de Windows para aplicaciones para UWP
  5. Selecciona Instalar y, después, Aceptar.

Almacenamiento provisional de la aplicación de Windows

Agregar al almacenamiento provisional la aplicación de Windows extrae y desempaqueta el contenido de la aplicación en un directorio local. Una vez que la aplicación de Windows está desempaquetada en la ubicación de almacenamiento provisional, puedes insertar archivos de corrección de PSF para corregir cualquier experiencia no deseada.

  1. En una ventana de PowerShell administrativa, establece las siguientes variables para establecer como destino el archivo de aplicación específico y la versión del SDK de Windows 10:

    $AppPath          = "C:\PSF\SourceApp\PSFSampleApp.msix"         ## Path to the MSIX App Installer
    $StagingFolder    = "C:\PSF\Staging\PSFSampleApp"                ## Path to where the MSIX App will be staged
    $OSArchitecture   = "x$((gwmi Win32_Processor).AddressWidth)"    ## Operating System Architecture
    $Win10SDKVersion  = "10.0.19041.0"                               ## Latest version of the Win10 SDK
    
  2. Desempaqueta la aplicación de Windows en la carpeta de almacenamiento provisional mediante la ejecución del siguiente cmdlet de PowerShell:

    ## Sets the directory to the Windows 10 SDK
    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    
    ## Unpackages the Windows app to the staging folder
    .\makeappx.exe unpack /p "$AppPath" /d "$StagingFolder"
    

Creación e inserción de los archivos PSF necesarios

Para corregir la aplicación de Windows, crea un archivo config.json con información sobre el iniciador de aplicaciones de Windows que produce un error. Si varios iniciadores de aplicaciones de Windows experimentan problemas, puedes configurar el archivo config.json con varias entradas.

Después de crear el archivo config.json, mueve los archivos config.json y las correcciones de apoyo de PSF a la raíz del paquete de la aplicación de Windows.

  1. Abre Visual Studio Code u otro editor de texto.

  2. Crea un nuevo archivo denominado config.json en el directorio de almacenamiento provisional de la aplicación de Windows, C:\PSF\Staging\PSFSampleApp.

  3. Copia el siguiente código en el archivo config.json recién creado.

    {
        "applications": [
            {
                "id": "",
                "executable": ""
            }
        ],
        "processes": [
            {
                "executable": "",
                "fixups": [
                {
                    "dll": "",
                    "config": {
                        "redirectedPaths": {
                            "packageRelative": [
                                {
                                    "base": "",
                                    "patterns": [
                                        ""
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
            }
        ]
    }
    
  4. Abre el archivo AppxManifest.xml en la carpeta de almacenamiento provisional de la aplicación de Windows. En el siguiente ejemplo se muestra un archivo AppxManifest.xml:

    <Applications>
        <Application Id="PSFSAMPLE" Executable="VFS\ProgramFilesX64\PS Sample App\PSFSample.exe" EntryPoint="Windows.FullTrustApplication">
        <uap:VisualElements BackgroundColor="transparent" DisplayName="PSFSample" Square150x150Logo="Assets\StoreLogo.png" Square44x44Logo="Assets\StoreLogo.png" Description="PSFSample">
            <uap:DefaultTile Wide310x150Logo="Assets\StoreLogo.png" Square310x310Logo="Assets\StoreLogo.png" Square71x71Logo="Assets\StoreLogo.png" />
        </uap:VisualElements>
        </Application>
    </Applications>
    
  5. Realiza los siguientes cambios en el archivo config.json:

    • Establece el valor applications.id como el mismo que en el campo Applications.Application.ID del archivo AppxManifest.xml.

      Image showing the location of the ID within the AppxManifest file.

    • Establece el valor applications.executable para establecer como destino la ruta de acceso relativa a la aplicación ubicada en el campo Applications.Application.Executable del archivo AppxManifest.xml.

      Image showing the location of the executable within the *AppxManifest.xml* file.

    • Establece el valor applications.workingdirectory para establecer como destino la ruta de acceso de la carpeta relativa en el campo Applications.Application.Executable del archivo AppxManifest.xml.

      Image showing the location of the working directory within the AppxManifest file.

    • Establece el valor process.executable como destino del nombre de archivo, sin ruta de acceso y extensión, en el campo Applications.Application.Executable del archivo AppxManifest.xml.

      Image showing the location of the process executable within the AppxManifest file.

    • Establece el valor processes.fixups.dll para establecer como destino FileRedirectionFixup.dll que es específico de arquitectura. Si la corrección es para la arquitectura x64, establece el valor en FileRedirectionFixup64.dll. Si la arquitectura es x86 o es desconocida, establece el valor en FileRedirectionFixup86.dll.

    • Establece el valor processes.fixups.config.redirectedPaths.packageRelative.base en la ruta de acceso de la carpeta relativa al paquete en el campo Applications.Application.Executable del archivo AppxManifest.xml.

      Image showing the location of the working directory within the AppxManifest file.

    • Establece el valor processes.fixups.config.redirectedPaths.packageRelative.patterns para que coincida con el tipo de archivo que crea la aplicación. Si usas .*\\.log, PSF redirige todas las escrituras del archivo de registro en el directorio processes.fixups.config.redirectedPaths.packageRelative.base y los directorios secundarios.

  6. Guarda el archivo config.json actualizado. En el ejemplo siguiente se muestra un archivo config.json actualizado:

    {
        "applications": [
            {
            "id": "PSFSample",
            "executable": "VFS/ProgramFilesX64/PS Sample App/PSFSample.exe"
            }
        ],
        "processes": [
            {
                "executable": "PSFSample",
                "fixups": [
                    {
                        "dll": "FileRedirectionFixup64.dll",
                        "config": {
                            "redirectedPaths": {
                                "packageRelative": [
                                    {
                                        "base": "VFS/ProgramFilesX64/PS Sample App/",
                                        "patterns": [
                                            ".*\\.log"
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                ]
            }
        ]
    }
    
  7. Copia los siguientes archivos del Marco de compatibilidad de paquete para la arquitectura ejecutable de la aplicación en la raíz de la aplicación de Windows preconfigurada. Puedes encontrar los archivos en .\Microsoft.PackageSupportFramework.\<Version>\bin.

    Aplicación (x64) Aplicación (x86)
    PSFLauncher64.exe PSFLauncher32.exe
    PSFRuntime64.dll PSFRuntime32.dll
    PSFRunDll64.exe PSFRunDll32.exe
    FileRedirectionFixup64.dll FileRedirectionFixup64.dll

Actualización de AppxManifest

Después de crear y actualizar el archivo config.json, actualiza el archivo AppxManifest.xml de la aplicación de Windows para cada iniciador de aplicaciones de Windows que hayas incluido en config.json. El archivo AppxManifest.xmlApplications debe tener como destino PSFLauncher.exe asociado a la arquitectura de la aplicación.

  1. Abre AppxManifest.xml en la carpeta de la aplicación MSIX de almacenamiento provisional, C:\PSF\Staging\PSFSampleApp.
  2. Actualiza AppxManifest.xml con el código siguiente:
    <Package ...>
    ...
    <Applications>
        <Application Id="PSFSample"
                    Executable="PSFLauncher32.exe"
                    EntryPoint="Windows.FullTrustApplication">
        ...
        </Application>
    </Applications>
    </Package>
    

Reempaquetar la aplicación

Después de aplicar todas las correcciones, vuelve a empaquetar la aplicación de Windows en un MSIX e inicia sesión con un certificado de firma de código.

  1. Abre una Ventana administrativa de PowerShell.

  2. Configure las siguientes variables:

    $AppPath          = "C:\PSF\SourceApp\PSFSampleApp_Updated.msix" ## Path to the MSIX App Installer
    $CodeSigningCert  = "C:\PSF\Cert\CodeSigningCertificate.pfx"     ## Path to your code signing certificate
    $CodeSigningPass  = "<Password>"                                 ## Password used by the code signing certificate
    $StagingFolder    = "C:\PSF\Staging\PSFSampleApp"                ## Path to where the MSIX App will be staged
    $OSArchitecture   = "x$((gwmi Win32_Processor).AddressWidth)"    ## Operating System Architecture
    $Win10SDKVersion  = "10.0.19041.0"                               ## Latest version of the Win10 SDK
    
  3. Vuelve a empaquetar la aplicación de Windows desde la carpeta de almacenamiento provisional mediante la ejecución del siguiente cmdlet de PowerShell:

    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    .\makeappx.exe pack /p "$AppPath" /d "$StagingFolder"
    
  4. Ejecuta el siguiente cmdlet de PowerShell para firmar la aplicación de Windows:

    Set-Location "${env:ProgramFiles(x86)}\Windows Kits\10\Bin\$Win10SDKVersion\$OSArchitecture"
    .\signtool.exe sign /v /fd sha256 /f $CodeSigningCert /p $CodeSigningPass $AppPath