【问题标题】:Opening Folder or to Selected File in Single, Usable Instance在单个可用实例中打开文件夹或选择文件
【发布时间】:2016-07-26 06:16:08
【问题描述】:

我正在尝试在我的应用程序中创建一个“显示”按钮。我希望它可以在所选文件夹中打开 Windows 资源管理器,或者在文件夹中打开并突出显示所选文件。

我知道 Process.Start("explorer.exe", fileName) 会这样做,但是它会在无法导航的资源管理器版本中打开。例如,按“向上目录”会打开一个新窗口。

下面的代码可以满足我的所有需求,除了路径是文件时,每次单击按钮时都会打开一个新的窗口实例。而当路径是一个文件夹时,它会打开一个已经存在的窗口(如果该路径上存在一个窗口)。

我希望我可以拥有相同的文件选择功能。但我不知道该怎么做。

感谢您的任何帮助!

static void OpenInWin(string path) {
    path = path.Replace("/", "\\");

    ProcessStartInfo pi = new ProcessStartInfo("explorer.exe") {
        WindowStyle = ProcessWindowStyle.Normal,
        UseShellExecute = true
    };

    if (Directory.Exists(path)) { // We are opening a directory
        pi.FileName = path;
        pi.Verb = "open";
    } else {
        pi.Arguments = "/select, \"" + new FileInfo(path).FullName + "\"";
    }

    try {
        Process.Start(pi);
    } catch(Exception e) {
        UnityEngine.Debug.Log(e);
    }
}

【问题讨论】:

    标签: c# process windows-explorer file-browser


    【解决方案1】:

    下面的方法将从传递的路径中获取目录,然后打开该目录。打开该目录后,它将关注文件名(如果存在)。

    记得为SendKeys 加上using System.Windows.Forms;

    static void OpenInWin(string path)
    {
        path = path.Replace("/", "\\");
        FileInfo fileInfo = new FileInfo(path);
    
        //check if directory exists so that 'fileInfo.Directory' doesn't throw directory not found
    
        ProcessStartInfo pi = new ProcessStartInfo("explorer.exe")
        {
            WindowStyle = ProcessWindowStyle.Normal,
            UseShellExecute = true,
            FileName = fileInfo.Directory.FullName,
            Verb = "open"
        };
    
        try
        {
            Process.Start(pi);
            Thread.Sleep(500); // can set any delay here
            SendKeys.SendWait(fileInfo.Name);
        }
        catch (Exception e)
        {
            throw new Exception(e.Message, e);
        }
    }
    


    注意:可能有更好的方法将密钥发送到进程。您可以尝试以下方法:

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
    public static void SendKey()
    {
        Process notepad = new Process();
        notepad.StartInfo.FileName = @"C:\Windows\Notepad.exe";
        notepad.Start();
    
        notepad.WaitForInputIdle();
    
        IntPtr p = notepad.MainWindowHandle;
        ShowWindow(p, 1);
        SendKeys.SendWait("Text sent to notepad");
    }
    

    编辑:

    要在没有 Windows 窗体上下文的情况下生成关键事件, 我们可以使用下面的方法,

    [DllImport("user32.dll")]
    public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
    

    示例代码如下:

    const int VK_UP = 0x26; //up key
        const int VK_DOWN = 0x28;  //down key
        const int VK_LEFT = 0x25;
        const int VK_RIGHT = 0x27;
        const uint KEYEVENTF_KEYUP = 0x0002;
        const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
       static int press()
       {
    
    //Press the key
            keybd_event((byte)VK_UP, 0, KEYEVENTF_EXTENDEDKEY | 0, 0);
            return 0; 
    
       }
    

    定义了虚拟键列表here

    要获得完整的图片,请使用以下链接, http://tksinghal.blogspot.in/2011/04/how-to-press-and-hold-keyboard-key.html

    【讨论】:

    • 嘿!谢谢你。不幸的是,我无法测试它,因为我使用的是 Unity,我认为它只使用 .net 2.0?而且 System.Windows 的出现似乎比那晚?
    • 我昨天的评论(在理解了问题之后)是你今天的答案,很好;)@stuntboots System.Windows 在 Unity 之前出现了。我已经编辑了答案,向您展示如何在没有 Windows 窗体上下文的情况下生成关键事件。
    • @stuntboots 如果你迁移到 Unity 5,你可以使用 .Net 3.5
    • 嗨安东尼,我实际上在 Unity 5 上!如何更改为升级后的 .Net?
    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 2011-04-25
    • 1970-01-01
    • 2012-02-02
    • 2010-09-24
    • 2013-12-26
    • 2015-04-22
    • 1970-01-01
    相关资源
    最近更新 更多