Skip to main content
Inspiring
March 20, 2025
Answered

an "Explorer" style dialog window instead of classic dialog in Windows using folder.selectDialog()?

  • March 20, 2025
  • 1 reply
  • 347 views

I've made a script that uses folder.selectDialog() to bring up a folder location save window. It works perfect in OSX, but in Windows it brings up a "classic" windows dialog box instead of of the more robust "Explorer" style window.  I've tried a few other methods but no success.  Any verified way to bring up an Explorer style window with an After Effects script  (without going too complex).  thanks.

Correct answer Aaron Cobb

This is what I use, a cross-platform method that runs a PowerShell script to access the more modern(ish) folder picker dialog. Credit for this method is in the commented URL in the script.

 

// Better Windows folder picker via an elaborate powershell script
function betterFolderPicker(pickerTitle, defaultFolder)
{
	function powerShellCall(commandString)
	{
		return system.callSystem('cmd.exe /c powershell.exe -c "' + commandString +'"');
	}
	var folderForTempFiles = Folder.temp.fsName;
	//create a new textfile for writing the folder path from PowerShell
	var scratchFileName = "/ExtendscriptFolderPickerTempFile.txt";
	var scratchFile = new File(folderForTempFiles + scratchFileName);
	var chosenFolder = null;
	var chosenPath = null;

	if($.os.match(/Windows/) != null)
	{
		// powershell script courtesy of https://www.reddit.com/r/PowerShell/comments/9s0q6k/folder_browser_dialog_with_an_address_bar/
		var powerShellScript = "$AssemblyFullName = 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'\
		$Assembly = [System.Reflection.Assembly]::Load($AssemblyFullName)\
		$OpenFileDialog = [System.Windows.Forms.OpenFileDialog]::new()\
		$OpenFileDialog.AddExtension = $false\
		$OpenFileDialog.CheckFileExists = $false\
		$OpenFileDialog.DereferenceLinks = $true\
		$OpenFileDialog.Filter = 'Folders|`n'\
		$OpenFileDialog.Multiselect = $false\
		$OpenFileDialog.Title = '" + pickerTitle + "'\
		$OpenFileDialog.InitialDirectory = '" + defaultFolder.fsName + "'\
		$OpenFileDialogType = $OpenFileDialog.GetType()\
		$FileDialogInterfaceType = $Assembly.GetType('System.Windows.Forms.FileDialogNative+IFileDialog')\
		$IFileDialog = $OpenFileDialogType.GetMethod('CreateVistaDialog',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$null)\
		$null = $OpenFileDialogType.GetMethod('OnBeforeVistaDialog',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$IFileDialog)\
		[uint32]$PickFoldersOption = $Assembly.GetType('System.Windows.Forms.FileDialogNative+FOS').GetField('FOS_PICKFOLDERS').GetValue($null)\
		$FolderOptions = $OpenFileDialogType.GetMethod('get_Options',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$null) -bor $PickFoldersOption\
		$null = $FileDialogInterfaceType.GetMethod('SetOptions',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$FolderOptions)\
		$VistaDialogEvent = [System.Activator]::CreateInstance($AssemblyFullName,'System.Windows.Forms.FileDialog+VistaDialogEvents',$false,0,$null,$OpenFileDialog,$null,$null).Unwrap()\
		[uint32]$AdviceCookie = 0\
		$AdvisoryParameters = @($VistaDialogEvent,$AdviceCookie)\
		$AdviseResult = $FileDialogInterfaceType.GetMethod('Advise',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$AdvisoryParameters)\
		$AdviceCookie = $AdvisoryParameters[1]\
		$Result = $FileDialogInterfaceType.GetMethod('Show',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,[System.IntPtr]::Zero)\
		$null = $FileDialogInterfaceType.GetMethod('Unadvise',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$AdviceCookie)\
		if ($Result -eq [System.Windows.Forms.DialogResult]::OK) {\
		$FileDialogInterfaceType.GetMethod('GetResult',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$null)\
		}\
		$OpenFileDialog.FileName > \"" + scratchFile.fsName + "\"";

		var formattedScript = powerShellScript.replace(/\t+/g, "").replace(/[\r\n]+/g, "; ");
		powerShellCall(formattedScript);

		scratchFile.open("r");
		chosenPath = scratchFile.readln();
		scratchFile.close();
		scratchFile.remove();
		if(chosenPath == "") chosenFolder == null
		else chosenFolder = new Folder(File.encode(chosenPath));
	}
	else
	{
			chosenFolder = defaultFolder.selectDlg(pickerTitle);
	}
	return chosenFolder;
}

 

1 reply

Aaron CobbCorrect answer
Inspiring
March 26, 2025

This is what I use, a cross-platform method that runs a PowerShell script to access the more modern(ish) folder picker dialog. Credit for this method is in the commented URL in the script.

 

// Better Windows folder picker via an elaborate powershell script
function betterFolderPicker(pickerTitle, defaultFolder)
{
	function powerShellCall(commandString)
	{
		return system.callSystem('cmd.exe /c powershell.exe -c "' + commandString +'"');
	}
	var folderForTempFiles = Folder.temp.fsName;
	//create a new textfile for writing the folder path from PowerShell
	var scratchFileName = "/ExtendscriptFolderPickerTempFile.txt";
	var scratchFile = new File(folderForTempFiles + scratchFileName);
	var chosenFolder = null;
	var chosenPath = null;

	if($.os.match(/Windows/) != null)
	{
		// powershell script courtesy of https://www.reddit.com/r/PowerShell/comments/9s0q6k/folder_browser_dialog_with_an_address_bar/
		var powerShellScript = "$AssemblyFullName = 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'\
		$Assembly = [System.Reflection.Assembly]::Load($AssemblyFullName)\
		$OpenFileDialog = [System.Windows.Forms.OpenFileDialog]::new()\
		$OpenFileDialog.AddExtension = $false\
		$OpenFileDialog.CheckFileExists = $false\
		$OpenFileDialog.DereferenceLinks = $true\
		$OpenFileDialog.Filter = 'Folders|`n'\
		$OpenFileDialog.Multiselect = $false\
		$OpenFileDialog.Title = '" + pickerTitle + "'\
		$OpenFileDialog.InitialDirectory = '" + defaultFolder.fsName + "'\
		$OpenFileDialogType = $OpenFileDialog.GetType()\
		$FileDialogInterfaceType = $Assembly.GetType('System.Windows.Forms.FileDialogNative+IFileDialog')\
		$IFileDialog = $OpenFileDialogType.GetMethod('CreateVistaDialog',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$null)\
		$null = $OpenFileDialogType.GetMethod('OnBeforeVistaDialog',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$IFileDialog)\
		[uint32]$PickFoldersOption = $Assembly.GetType('System.Windows.Forms.FileDialogNative+FOS').GetField('FOS_PICKFOLDERS').GetValue($null)\
		$FolderOptions = $OpenFileDialogType.GetMethod('get_Options',@('NonPublic','Public','Static','Instance')).Invoke($OpenFileDialog,$null) -bor $PickFoldersOption\
		$null = $FileDialogInterfaceType.GetMethod('SetOptions',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$FolderOptions)\
		$VistaDialogEvent = [System.Activator]::CreateInstance($AssemblyFullName,'System.Windows.Forms.FileDialog+VistaDialogEvents',$false,0,$null,$OpenFileDialog,$null,$null).Unwrap()\
		[uint32]$AdviceCookie = 0\
		$AdvisoryParameters = @($VistaDialogEvent,$AdviceCookie)\
		$AdviseResult = $FileDialogInterfaceType.GetMethod('Advise',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$AdvisoryParameters)\
		$AdviceCookie = $AdvisoryParameters[1]\
		$Result = $FileDialogInterfaceType.GetMethod('Show',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,[System.IntPtr]::Zero)\
		$null = $FileDialogInterfaceType.GetMethod('Unadvise',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$AdviceCookie)\
		if ($Result -eq [System.Windows.Forms.DialogResult]::OK) {\
		$FileDialogInterfaceType.GetMethod('GetResult',@('NonPublic','Public','Static','Instance')).Invoke($IFileDialog,$null)\
		}\
		$OpenFileDialog.FileName > \"" + scratchFile.fsName + "\"";

		var formattedScript = powerShellScript.replace(/\t+/g, "").replace(/[\r\n]+/g, "; ");
		powerShellCall(formattedScript);

		scratchFile.open("r");
		chosenPath = scratchFile.readln();
		scratchFile.close();
		scratchFile.remove();
		if(chosenPath == "") chosenFolder == null
		else chosenFolder = new Folder(File.encode(chosenPath));
	}
	else
	{
			chosenFolder = defaultFolder.selectDlg(pickerTitle);
	}
	return chosenFolder;
}

 

Inspiring
March 26, 2025

Wow!  Thanks so much, I'll give it a try.  (had attempted a powershell thing, but no luck, hard to test being in OSX as well).
my semi workaround was to use var saveFile = defaultFile.saveDlg("Select folder and save");
the metho you provided is pretty deep, but no dobut will look like a "real" open dialog (not a "Save" dailog like mine).
thanks again!