简体   繁体   English

C#:System.Diagnostics.Process.Start(“Explorer.exe”,@“/ select”+ FilePath)。文件名为unicode字符时无法打开文件

[英]C#: System.Diagnostics.Process.Start(“Explorer.exe”, @“/select” + FilePath). Can not open file when file's name is unicode character

I want to open file's location with window Explorer. 我想用窗口资源管理器打开文件的位置。 I am using C# with code 我正在使用C#代码

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). 它适用于简单的英文字符,但如果文件的名称是Unicode字符(Thia语言),则无法打开文件的位置。

Anyone could help please? 有人可以帮忙吗?

试着把它放在引号中:

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

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. 在Windows 7中,文件已创建并在资源管理器中正确显示。 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. 更有可能是映射到E:驱动器的文件系统出现问题。 Like a FAT32 volume on a flash drive or a network redirector. 像闪存驱动器或网络重定向器上的FAT32卷一样。 Ask questions about that, respectively, at superuser.com and serverfault.com. 分别在superuser.com和serverfault.com上提出相关问题。 Do not forget to document those essential details. 不要忘记记录这些基本细节。

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. 确保它存在。

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. 这是我已经确定的交易:至少从Windows 8.1开始, “Explorer.exe”似乎在查找文件之前删除所有组合字符 You can test this either in c# or a console (do chcp 65001 first to get in unicode mode). 您可以在c#或控制台中测试它(首先执行chcp 65001以进入unicode模式)。 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. 问题不是非ascii :相反,它是具有可组合字符的文件名。 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 . 好消息是,有一种不同的方式可以打开这些没有这个问题的方法, @ bert-huijben在这个答案对此进行了描述。

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);
        }
    }

The following code works for me with files with korean characters (are unicode characters). 以下代码适用于包含韩文字符(unicode字符)的文件。 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);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM