1

Even though this question has already been asked before, the code proposed in the answers didn't get me much further so maybe someone can shed light on this.

I got most of the code from this answered question.

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

Basically what I want to achieve is to have this method return the full path of the window that corresponds to the handle. The method will later on be used externally using the .DLL that this code is compiled into.

The problem I have is that for some reason explorer is always NULL and thus doesn't return a path.

I'd be happy if anyone could shed some light on this, so that I and probably other people who have problems on that matter may know what to do here.

Community
  • 1
  • 1
FBC
  • 11
  • 2
  • What will your app do longer term? if you wish it to be available as a context menu etc, the file you click against will send the full path.. some of this therefore maybe unnecessary – BugFinder Apr 27 '16 at 10:06
  • Ah, basically I need to implement it into our actual programming language, Windev, which I can achieve by loading it as a .dll. In longterm I want to achieve drag and drop from the program into the explorer, however not through C# but through Windev. – FBC Apr 27 '16 at 10:11
  • Hmm, not an area I tried yet.. I would imagine however, that as long as the dragged item is set to claim its a file and so on, explorer would see it just as vmware allows you to drag drop from outside the os to inside the vm etc.. – BugFinder Apr 27 '16 at 10:19
  • In the actual software I already implemented the drag/drop from the explorer inside the program, however not the otherway around. With the explorer path of the currently hovered window (of which I can obtain the handle within Windev), I could implement the opposite drag/drop operation (program to explorer) – FBC Apr 27 '16 at 10:26

2 Answers2

1

Here is how I print the directory of each explorer window:

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

The address format is file:///C:/Program%20Files/....

You can parse this address format to the one you want (By removing the file:/// prefix and replacing / with \) & also decoding the HTML encoding.

Community
  • 1
  • 1
shlatchz
  • 1,612
  • 1
  • 18
  • 40
  • nice :) might be worth giving an example of the output - I notice it is a `file:` uri. – Keith Hall Apr 27 '16 at 10:36
  • Thank you for your answer! I tried to implement this in a console application just to test the output, however for some reason it doesn't run into the final "if" due to the itemname being null. Am I using it wrong by any chance? – FBC Apr 27 '16 at 10:43
  • Nevermind, the itemname in my case was "Windows-Explorer" instead of "Windows Explorer", it actually prints the directory of each explorer window now, exactly as it should. Now the only question would be how I could obtain just one of the paths through a window handle. – FBC Apr 27 '16 at 11:12
0

Thanks to shlatchz answer and various approaches from similar topics, I found a way to obtain the path through the handle of the window. It's more or less a mix of all of them and I hope it will help people looking exactly for this in the future.

        //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;



    }

The path returned will be in the same format as provided in shlatchz answer file:///C:/Program%20Files/...

FBC
  • 11
  • 2