10

I am searching for a way to obtain a proper file:/ URI from inside Windows Explorer. Basically I would like to have a context menu entry which says "copy file URI to clipboard". Does something like that exist?

This is not a duplicate of "Copy filename to clipboard" since I want a file URI and not the path name.

To clarify: I am looking to get "file:///c:/Temp/foo%20bar.txt" and neither "C:\Temp\foo bar.txt" nor "foo bar.txt" nor "C:\Temp".

2 Answers2

3

Just came up with this VBS.

If WScript.arguments.count > 0 Then
    Dim WshShell: Set WshShell = WScript.CreateObject("Wscript.Shell")
    strPath = "file:///" & Wscript.Arguments(0)
    strPath = Replace(strPath,"\","/")
    strPath = Replace(strPath," ","%20")
    sCmd = "%comspec% /c<nul (set/p anyvariable=" & Chr(34) & strPath & Chr(34) & ")|clip.exe"
    WshShell.Run sCmd,0,0
    Set WshShell = Nothing
End If

Save it as a .VBS file. Drag and drop a file on to the VBScript and it copies the file's URI to clipboard. You can implement it in the right-click menu if required.

It copies the file name to memory, reverses the slashes, replaces spaces with "%20", and appends "file:///" at the beginning. It's a basic script which supports only one file name / argument. You can modify it as required.

Add the Script to your Send To folder

You may place a shortcut of the script in your Send To folder. Press WinKey + R, type shell:sendto and press ENTER. Create a shortcut to the script in the Send To folder and name it accordingly. (eg. Copy File URI)

Now, right-click a file, click Send To and click Copy File URI. The file path would be copied to the clipboard, in the URI format as below.

file:///C:/Users/jack/desktop/list-of-items.txt
w32sh
  • 12,379
1

The VBS script is nice, but there is no way it handles all the edge cases handled by the likes of UrlCreateFromPath or .NET's System.URI.

Fortunately, both are easy to use, here's what I did:

using System;
using System.Windows.Forms;

namespace AbsoluteUriGenerator
{
    class Program
    {
        [STAThread]
        static int Main(string[] args)
        {
            if (args.Length != 1)
            {
                var executableName = typeof(Program).Assembly.GetName().Name + ".exe";
                Console.WriteLine("Usage: {0} pathToConvert", executableName);
                Console.WriteLine("Example: {0} \"C:\\foo\"", executableName);
                return 1;
            }

            var path = args[0];
            Console.WriteLine("Resolving file:// URI of path: {0}", path);
            var fileUri = new Uri(path).AbsoluteUri;

            Console.WriteLine("Setting clipboard to resolved file:// URI: {0}", fileUri);
            Clipboard.SetText(fileUri);
            return 0;
        }
    }
}

You can copy it to your shell:sendto folder, here's a compiled version: https://1drv.ms/u/s!Aj2cMNVj29ben4B_mh9Md5R4ghBlMQ