88using System . Linq ;
99using System . Net ;
1010using System . Runtime . CompilerServices ;
11+ using System . Runtime . InteropServices ;
1112using System . Threading ;
1213using System . Threading . Tasks ;
1314using System . Windows ;
@@ -320,47 +321,98 @@ public void SavePluginSettings()
320321 ( ( PluginJsonStorage < T > ) _pluginJsonStorages [ type ] ) . Save ( ) ;
321322 }
322323
323- public void OpenDirectory ( string DirectoryPath , string FileNameOrFilePath = null )
324+ [ DllImport ( "shell32.dll" , CharSet = CharSet . Unicode ) ]
325+ private static extern int SHParseDisplayName (
326+ [ MarshalAs ( UnmanagedType . LPWStr ) ] string name ,
327+ IntPtr bindingContext ,
328+ out IntPtr pidl ,
329+ uint sfgaoIn ,
330+ out uint psfgaoOut
331+ ) ;
332+
333+ [ DllImport ( "shell32.dll" ) ]
334+ private static extern int SHOpenFolderAndSelectItems (
335+ IntPtr pidlFolder ,
336+ uint cidl ,
337+ [ MarshalAs ( UnmanagedType . LPArray ) ] IntPtr [ ] apidl ,
338+ uint dwFlags
339+ ) ;
340+
341+ [ DllImport ( "ole32.dll" ) ]
342+ private static extern void CoTaskMemFree ( IntPtr pv ) ;
343+
344+ private void OpenFolderAndSelectItem ( string filePath )
324345 {
346+ IntPtr pidlFolder = IntPtr . Zero ;
347+ IntPtr pidlFile = IntPtr . Zero ;
348+ uint attr ;
349+
350+ string folderPath = Path . GetDirectoryName ( filePath ) ;
351+
325352 try
326353 {
327- using var explorer = new Process ( ) ;
354+ SHParseDisplayName ( folderPath , IntPtr . Zero , out pidlFolder , 0 , out attr ) ;
355+ SHParseDisplayName ( filePath , IntPtr . Zero , out pidlFile , 0 , out attr ) ;
356+
357+ if ( pidlFolder != IntPtr . Zero && pidlFile != IntPtr . Zero )
358+ {
359+ SHOpenFolderAndSelectItems ( pidlFolder , 1 , new [ ] { pidlFile } , 0 ) ;
360+ }
361+ }
362+ finally
363+ {
364+ if ( pidlFile != IntPtr . Zero )
365+ CoTaskMemFree ( pidlFile ) ;
366+ if ( pidlFolder != IntPtr . Zero )
367+ CoTaskMemFree ( pidlFolder ) ;
368+ }
369+ }
370+
371+ public void OpenDirectory ( string directoryPath , string fileNameOrFilePath = null )
372+ {
373+ try
374+ {
375+ string targetPath = fileNameOrFilePath is null
376+ ? directoryPath
377+ : Path . IsPathRooted ( fileNameOrFilePath )
378+ ? fileNameOrFilePath
379+ : Path . Combine ( directoryPath , fileNameOrFilePath ) ;
380+
328381 var explorerInfo = _settings . CustomExplorer ;
329382 var explorerPath = explorerInfo . Path . Trim ( ) . ToLowerInvariant ( ) ;
330- var targetPath = FileNameOrFilePath is null
331- ? DirectoryPath
332- : Path . IsPathRooted ( FileNameOrFilePath )
333- ? FileNameOrFilePath
334- : Path . Combine ( DirectoryPath , FileNameOrFilePath ) ;
335383
336384 if ( Path . GetFileNameWithoutExtension ( explorerPath ) == "explorer" )
337385 {
338- // Windows File Manager
339- explorer . StartInfo = new ProcessStartInfo
386+ if ( fileNameOrFilePath is null )
340387 {
341- FileName = "explorer.exe" ,
342- Arguments = FileNameOrFilePath is null
343- ? DirectoryPath // only open the directory
344- : $ "/select,\" { targetPath } \" ", // open the directory and select the file
345- UseShellExecute = true
346- } ;
388+ // 폴더만 열기
389+ Process . Start ( new ProcessStartInfo
390+ {
391+ FileName = directoryPath ,
392+ UseShellExecute = true
393+ } ) ? . Dispose ( ) ;
394+ }
395+ else
396+ {
397+ // SHOpenFolderAndSelectItems 방식
398+ OpenFolderAndSelectItem ( targetPath ) ;
399+ }
347400 }
348401 else
349402 {
350- // Custom File Manager
351- explorer . StartInfo = new ProcessStartInfo
403+ // 커스텀 파일 관리자
404+ var shellProcess = new ProcessStartInfo
352405 {
353- FileName = explorerInfo . Path . Replace ( "%d" , DirectoryPath ) ,
406+ FileName = explorerInfo . Path . Replace ( "%d" , directoryPath ) ,
354407 UseShellExecute = true ,
355- Arguments = FileNameOrFilePath is null
356- ? explorerInfo . DirectoryArgument . Replace ( "%d" , DirectoryPath )
408+ Arguments = fileNameOrFilePath is null
409+ ? explorerInfo . DirectoryArgument . Replace ( "%d" , directoryPath )
357410 : explorerInfo . FileArgument
358- . Replace ( "%d" , DirectoryPath )
411+ . Replace ( "%d" , directoryPath )
359412 . Replace ( "%f" , targetPath )
360413 } ;
414+ Process . Start ( shellProcess ) ? . Dispose ( ) ;
361415 }
362-
363- explorer . Start ( ) ;
364416 }
365417 catch ( Win32Exception ex ) when ( ex . NativeErrorCode == 2 )
366418 {
@@ -384,6 +436,7 @@ public void OpenDirectory(string DirectoryPath, string FileNameOrFilePath = null
384436 }
385437 }
386438
439+
387440 private void OpenUri ( Uri uri , bool ? inPrivate = null )
388441 {
389442 if ( uri . Scheme == Uri . UriSchemeHttp || uri . Scheme == Uri . UriSchemeHttps )
0 commit comments