📢 PS-SFTA Latest Update 2020-09-14
Tested in: 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
In our previous post we shared a command line tool to associate an application with a specific file type, however one of our visitors could not use the tool in his work environment due to restrictions because they could not use third-party executable applications, and told us that he wanted to do it using PowerShell.
Taking into account his very interesting idea and our passion for the world of scripting and sysadmin, we decided to create a simple version of SFTA in PowerShell using the Add-Type command that allows us to compile .NET code and use it in our Powershell instance. This is the Old Version. Use GitHub Version Instead.
Old PowerShell Script Using IApplicationAssociationRegistrationInternal
$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 "";
}
}
}
"@
if (-not ([System.Management.Automation.PSTypeName]'SFTA.AssocReg').Type)
{
Add-Type -TypeDefinition $sourceCSharp -Language CSharp
}
$assocProgram=[SFTA.AssocReg]::GetFileTypeAssociation(".pdf")
Write-Host(".PDF Assoc Program = " + $assocProgram)
[SFTA.AssocReg]::SetFileTypeAssociation("Applications\SumatraPDF.exe",".pdf")
PS-SFTA Latest Version
Sample Usage:
Set Acrobat Reader DC as Default .pdf reader:
Set-FTA "Applications\SumatraPDF.exe" .pdf
We hope this will be useful for you!!!
Doesn’t work on Win10 1809 🙁
Hi, this doesn’t work in new Windows 10 versions, Microsoft fixed it, you can check our SFTA command-line tool which is functional.
Microsoft fixed it, as in blocked the script from being able to do this? Or Microsoft fixed it as in the script works now?
It means the script will not work. Microsoft blocked/changed the Interface method that allowed to do it, but You can take a look at our command-line tool ‘SFTA’ It works.
What allows the command line tool to work and not the script?
It does not use the Interface. It use a new method. You can check source code on github. Regards
Thanks a lot for the update !
Impressive work! It is too hard to find a working powershell solution to change the default webbrowser. Your script works very well.
Thank you for your comment Rockschuppen We are happy it helps you.
Regards
Just wanted to reach out and say thanks for converting it to powershell! amazing work
It was a great pleasure. Thank you!!!
Best Regards