6

I want to open file's location with window Explorer. I am using C# with code

System.Diagnostics.Process.Start("Explorer.exe", @"/select," + FilePath)

it works well with simple English character, but it could not open the file's location if the file's name is Unicode character (Thia language).

Anyone could help please?

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
HIA YongKuy
  • 119
  • 1
  • 3
  • I've determined that the problem is words with Thai vowels that are composed with the consonant characters. E.g. ภาษาไทย ("Thai language") works fine, but ปู (crab) fails. The obvious difference is unicode normalization form; my understanding is that Windows NFC and NFD forms of a filename as unequal. But I haven't worked out how to get around this yet; just calling ````mystring.Normalize(...)```` on the argument doesn't help. – John Hatton May 22 '15 at 21:53

5 Answers5

3

Try putting it in quotes:

System.Diagnostics.Process.Start("Explorer.exe", @"/select,""" + FilePath + "\"")
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
2

No trouble with this code snippet:

    static void Main(string[] args) {
        string path = @"c:\temp\លួចស្រលាញ់សង្សារគេ.DAT";
        System.IO.File.WriteAllText(path, "hello");
        string txt = System.IO.File.ReadAllText(path);
    }

Windows 7, the file is created and displays correctly in Explorer. You didn't document your operating system version so that's one failure mode, albeit a very small one. Much more likely is trouble with the file system that's mapped to your E: drive. Like a FAT32 volume on a flash drive or a network redirector. Ask questions about that, respectively, at superuser.com and serverfault.com. Do not forget to document those essential details.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

Explorer will go to a default folder in this case 'My Documents', if the folder you are attempting to open is not there. Make sure it exists.

JonathanC
  • 180
  • 7
0

Here's the deal as far as I've determined: at least as of Windows 8.1, "Explorer.exe" appears to strip out all combining characters before looking for the file. You can test this either in c# or a console (do chcp 65001 first to get in unicode mode). If you try to open a target named ปู (thai for "crab") it won't work, but if you remove the vowel mark under so that you have just ป, it will work. Further, if you have a folder named ป and you as it to open ปู, it will open the ป folder!

This explains why some other devs had no problem; the problem is not non-ascii: rather, it is filenames with composable characters. Not all languages use them, and even in languages that do, not all file names have them.

The good news is, there's a different way to open these that doesn't have this problem, which is described by @bert-huijben in this answer.

For completeness, here's the version similar to what I ended up using:

    [DllImport("shell32.dll", ExactSpelling = true)]
    public static extern void ILFree(IntPtr pidlList);

    [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
    public static extern IntPtr ILCreateFromPathW(string pszPath);

    [DllImport("shell32.dll", ExactSpelling = true)]
    public static extern int SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);

    public void SelectItemInExplorer(string path)
    {
        var pidlList = ILCreateFromPathW(path);
        if(pidlList == IntPtr.Zero)
            throw new Exception(string.Format("ILCreateFromPathW({0}) failed",path));
        try
        {
            Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
        }
        finally
        {
            ILFree(pidlList);
        }
    }
Community
  • 1
  • 1
John Hatton
  • 1,734
  • 18
  • 20
0

The following code works for me with files with korean characters (are unicode characters). Please try it and let me know if it works.

       ...
       if (this.IsDirectory())
       {
          OpenFileWith("explorer.exe", this.FullPath, "/root,");
       }
       else
       {
          OpenFileWith("explorer.exe", this.FullPath, "/select,");
       }
      ...

    public static void OpenFileWith(string exePath, string path, string arguments)
    {
        if (path == null)
            return;

        try 
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.WorkingDirectory = Path.GetDirectoryName(path);
            if (exePath != null)
            {
                process.StartInfo.FileName = exePath;
                //Pre-post insert quotes for fileNames with spaces.
                process.StartInfo.Arguments = string.Format("{0}\"{1}\"", arguments, path);
            }
            else
            {
                process.StartInfo.FileName = path;
                process.StartInfo.WorkingDirectory = Path.GetDirectoryName(path);
            }
            if (!path.Equals(process.StartInfo.WorkingDirectory))
            {
                process.Start();
            }
        }
        catch(System.ComponentModel.Win32Exception ex) 
        {
            FormManager.DisplayException(ex, MessageBoxIcon.Information);
        }
    }
Daniel Peñalba
  • 30,507
  • 32
  • 137
  • 219