【问题标题】:Retrieve the full path of an explorer window through a handle in C#通过 C# 中的句柄检索资源管理器窗口的完整路径
【发布时间】:2021-08-07 03:00:28
【问题描述】:

即使之前已经提出过这个问题,但答案中提出的代码并没有让我更深入,所以也许有人可以阐明这一点。

我从this 得到了大部分代码,回答了问题。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace TestClassLibrary
{

  public class ClassTest
  {

    public ClassTest()
    {
    }

   public static void GetWindowPath(int handle, out string paths) {

        SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();
        var explorer = shellWindows.Cast<SHDocVw.InternetExplorer>().Where(hwnd => hwnd.HWND == handle).FirstOrDefault();
         if (explorer != null)
        {
            string path = new Uri(explorer.LocationURL).LocalPath;
            Console.WriteLine("name={0}, path={1}", explorer.LocationName, path);
            paths = path;
        }

        else
        {
            //Console.WriteLine("name={0}, path={1}", explorer.LocationName, path);
            paths = "Test";
       }
    }

基本上我想要实现的是让这个方法返回对应于句柄的窗口的完整路径。该方法稍后将使用此代码编译成的 .DLL 在外部使用。

我遇到的问题是,由于某种原因 explorer 总是 NULL,因此 不返回路径。

如果有人能对此有所了解,我会很高兴,这样我和可能在这件事上遇到问题的其他人可能知道该怎么做。

【问题讨论】:

  • 您的应用会长期做什么?如果您希望它作为上下文菜单等可用,您单击的文件将发送完整路径..因此其中一些可能是不必要的
  • 啊,基本上我需要将它实现到我们实际的编程语言Windev中,我可以通过将其加载为.dll来实现。从长远来看,我想实现从程序拖放到资源管理器中,但不是通过 C#,而是通过 Windev。
  • 嗯,不是我尝试过的区域.. 但是我想,只要将拖动的项目设置为声明其文件等等,资源管理器就会看到它,就像 vmware 允许你一样从操作系统外部拖放到虚拟机等内部。
  • 在实际的软件中,我已经在程序内部实现了资源管理器的拖放操作,但反之则不然。使用当前悬停窗口的资源管理器路径(我可以在Windev中获得句柄),我可以实现相反的拖放操作(程序到资源管理器)

标签: c#


【解决方案1】:

这是我如何打印每个资源管理器窗口的目录:

public void RefreshWindow()
{
    Guid CLSID_ShellApplication = new Guid("13709620-C279-11CE-A49E-444553540000");
    Type shellApplicationType = Type.GetTypeFromCLSID(CLSID_ShellApplication, true);

    object shellApplication = Activator.CreateInstance(shellApplicationType);
    object windows = shellApplicationType.InvokeMember("Windows", System.Reflection.BindingFlags.InvokeMethod, null, shellApplication, new object[] { });

    Type windowsType = windows.GetType();
    object count = windowsType.InvokeMember("Count", System.Reflection.BindingFlags.GetProperty, null, windows, null);
    Parallel.For(0, (int)count, i =>
    {
        object item = windowsType.InvokeMember("Item", System.Reflection.BindingFlags.InvokeMethod, null, windows, new object[] { i });
        Type itemType = item.GetType();
        string itemName = (string)itemType.InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, item, null);
        if (itemName == "Windows Explorer" || itemName == "File Explorer")
        {
            string currDirectory = (string)itemType.InvokeMember("LocationURL", System.Reflection.BindingFlags.GetProperty, null, item, null);
            Console.WriteLine(currDirectory);
        }
    });
}

地址格式为file:///C:/Program%20Files/...

您可以将此地址格式解析为您想要的格式(通过删除file:/// 前缀并将/ 替换为\)并解码HTML encoding

【讨论】:

  • nice :) 可能值得举一个输出示例 - 我注意到它是 file: uri。
  • 感谢您的回答!我试图在控制台应用程序中实现它只是为了测试输出,但是由于某些原因它没有运行到最终的“if”,因为 itemname 为空。我是不是用错了?
  • 没关系,在我的例子中,项目名称是“Windows-Explorer”而不是“Windows Explorer”,它现在实际上打印了每个资源管理器窗口的目录,就像它应该的那样。现在唯一的问题是我如何才能获得通过窗口句柄的路径之一。
【解决方案2】:

感谢 shlatchz 的回答和来自类似主题的各种方法,我找到了一种通过窗口句柄获取路径的方法。它或多或少是所有这些的混合体,我希望它能帮助人们在未来准确地寻找它。

        //Method to obtain the window path that corresponds to the handle passed
    public static string GetWindowPath(int handle)
    {
        //Default value for the variable returned at the end of the method if no path was found
        String Path = "";


        SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();


        foreach (SHDocVw.InternetExplorer window in shellWindows)
        {

            //If Window handle corresponds to passed handle
            if (window.HWND == handle)
            {
                //Print path of the respective folder and save it within the returned variable
                Console.WriteLine(window.LocationURL);
                Path = window.LocationURL;
                break;
            }

        }

        //If a path was found, retun the path, otherwise return ""
        return Path;



    }

返回的路径将与 shlatchz answer file:///C:/Program%20Files/... 中提供的格式相同

【讨论】:

    猜你喜欢
    • 2015-06-13
    • 1970-01-01
    • 2017-10-30
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多