在单个可用实例中打开文件夹或选择文件

Posted

技术标签:

【中文标题】在单个可用实例中打开文件夹或选择文件【英文标题】: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);
    

【问题讨论】:

【参考方案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? @stuntboots Target a Version of the .NET Framework

以上是关于在单个可用实例中打开文件夹或选择文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用批处理选择exe软件打开json文件?

vim命令

Vim命令合集

vim常用操作

VIM命令合集

vim常用命令