PowerShell Cambiar programa predeterminado asociado a una extensión Windows 10

? SFTA.exe Última Actualización 2022-04-17

Probado en: Windows 8, Windows 8.1, Windows 10 Version 1511, Windows 10 Version 1709, Windows 10 Version 1803, Windows 10 Version 1809, Windows 10 Version 1903, Windows 10 Version 1909, Windows 10 Version 20H2, Windows 11 Pro Version 21H2


En nuestra publicación anterior compartimos una herramienta de línea de comandos para asociar  una aplicación a  un tipo de archivo específico, sin embargo uno de nuestros visitantes no pudo usar la herramienta en su entorno de trabajo ya que por restricciones no podía usar aplicaciones ejecutables de terceros, y nos comentó que él deseaba hacerlo usando PowerShell.

Tomando en cuenta su idea tan interesante y nuestra pasión por el mundo del scripting y sysadmin decidimos crear una versión simple de SFTA en Powershell utilizando como base el comando Add-Type que nos permite compilar código .NET  y usarlo en nuestra instancia de PowerShell. Esta es la version antigua del script. Usar la última versión alojada en GitHub.

Antiguo Script de PowerShell usando IApplicationAssociationRegistrationInternal
##################################
##   __                         ##
##   |  \  _   _      _     _   ##
##   |__/ (_| | ) \/ _) \/ _)   ##
##                /     /       ##
##     © 2019 Danysys.com       ##
##       SFTA-PS v.1.0.0        ##
##################################

$sourceCSharp=@"
using System;
using System.Runtime.InteropServices;

namespace SFTA
{
    public static class AssocReg
    {


        [ComImport()]
        [Guid("14EBCC88-2831-4FC8-A5DF-9F36A81DB12C")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        private interface IApplicationAssociationRegistrationInternalW10_1709
        {
            [PreserveSig]
            void Dummy1();
            [PreserveSig]
            void SetProgIdAsDefault([MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName, [MarshalAs(UnmanagedType.LPWStr)] string pszSet, int atSetType);
            [PreserveSig]
            void Dummy3();
            [PreserveSig]
            void Dummy4();
            [PreserveSig]
            void Dummy5();
            [PreserveSig]
            void Dummy6();
            [PreserveSig]
            void QueryCurrentDefault([MarshalAs(UnmanagedType.LPWStr)] string pszExt, int atQueryType, int alQueryLevel, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszAssociation);
        }

        private interface IApplicationAssociationRegistrationInternalW8_1_63
        {
            [PreserveSig]
            void Dummy1();
            [PreserveSig]
            void SetProgIdAsDefault([MarshalAs(UnmanagedType.LPWStr)] string pszAppRegistryName, [MarshalAs(UnmanagedType.LPWStr)] string pszSet, int atSetType);
            [PreserveSig]
            void Dummy3();
            [PreserveSig]
            void Dummy4();
            [PreserveSig]
            void Dummy5();
            [PreserveSig]
            void Dummy6();
            [PreserveSig]
            void QueryCurrentDefault([MarshalAs(UnmanagedType.LPWStr)] string pszExt, int atQueryType, int alQueryLevel, [Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszAssociation);
        }

        [ComImport()]
        [Guid("591209c7-767b-42b2-9fba-44ee4615f2c7")]
        [ClassInterface(ClassInterfaceType.None)]
        private class ApplicationAssociationRegistration
        {
        }

        public static bool Debug  = false;
        private static readonly IApplicationAssociationRegistrationInternalW10_1709 AppAssocReg10 = new ApplicationAssociationRegistration() as IApplicationAssociationRegistrationInternalW10_1709;
        private static readonly IApplicationAssociationRegistrationInternalW8_1_63 AppAssocReg8 = new ApplicationAssociationRegistration() as IApplicationAssociationRegistrationInternalW8_1_63;

        private static void WriteDebug(string message)
        {
            if ( Debug)
            {
                Console.WriteLine(DateTime.Now.ToString("[yyyy.dd.MM HH:mm:ss]") + " "+ message);
            }
        }
        public static void SetFileTypeAssociation(string ProgramId,string Ext)
        {
            if (AppAssocReg10 != null)
            {
                WriteDebug("OK AppAssocReg10");
            AppAssocReg10.SetProgIdAsDefault(ProgramId, Ext, 0);
                return;
            }

            if (AppAssocReg8 != null)
            {
                WriteDebug("OK AppAssocReg8");
            AppAssocReg8.SetProgIdAsDefault(ProgramId,Ext, 0);
                return;
            }

            WriteDebug("FAIL AppAssocReg");

        }

        public static string GetFileTypeAssociation( string Ext)
        {
            
            if (AppAssocReg10 != null)
            {
                WriteDebug("OK AppAssocReg10");
                var assocApplication = "";
                AppAssocReg10.QueryCurrentDefault(Ext, 0, 1, out assocApplication);
                WriteDebug("assocApplication = " + assocApplication);
                return assocApplication;
            }

            if (AppAssocReg8 != null)
            {
                WriteDebug("OK AppAssocReg8");
                var assocApplication = "";
                AppAssocReg8.QueryCurrentDefault(Ext, 0, 1, out assocApplication);
                WriteDebug("assocApplication = " + assocApplication);
                return assocApplication;
            }


            WriteDebug("FAIL AppAssocReg");
            return "";

        }

    }
}
"@
#Add Type
if (-not ([System.Management.Automation.PSTypeName]'SFTA.AssocReg').Type)
{
    Add-Type -TypeDefinition $sourceCSharp -Language CSharp
}


#Sample Usage
#[SFTA.AssocReg]::Debug=$true; #Show Debug Information
#Get
$assocProgram=[SFTA.AssocReg]::GetFileTypeAssociation(".pdf")
Write-Host(".PDF Assoc Program = " + $assocProgram)
#Set
[SFTA.AssocReg]::SetFileTypeAssociation("Applications\SumatraPDF.exe",".pdf")

PS-SFTA Última Actualización

Ejemplo de uso:

Asignar Acrobat Reader DC como predeterminado para abrir archivos .pdf

Set-FTA AcroExch.Document.DC .pdf

Información adicional:

Asignar Microsoft Edge como predeterminado para abrir archivos .pdf desde la consola de Windows (cmd.exe)

powershell -ExecutionPolicy Bypass -command "& { . .\SFTA.ps1; Set-FTA 'MSEdgePDF' '.pdf' }"

Esperamos que les sea de utilidad!!!

10 comentarios en “PowerShell Cambiar programa predeterminado asociado a una extensión Windows 10

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *