はじめに
メールやチャットなどで、電子ファイルをやり取りするとき、フォルダ/ファイルのパスを書くことは、多いと思います。
XXです。
ご依頼の件、以下に格納しました。
<file://\\hoge\temp>
例の件.xlsx
以上、よろしくお願いいたします。
Windowsには、[Shift]キーを押しながらフォルダ/ファイルを右クリックしたときのコンテキストメニューに「パスのコピー」というものがありますが、コピーする(クリップボードに入る)パスは"[右クリックしたフォルダ/ファイルへのパス]"
なので、メールやチャットにそのまま貼ってもリンクにはならないという点で、残念でした。
それを解決するためのツール(実行形式)は既にあると思いますが、DOSコマンドで実現できれば、バッチファイルだけでなく、コンテキストメニューにも追加できるということで着手しました。
結論
今どき、誰もDOSコマンドを覚えたい、ということはないだろうと思うので、まずは結論です。
下記コードをバッチファイルにして、好きなフォルダ/ファイルをバッチファイルにD&Dすればよいです。
set /p <NUL="<file://%~1>" | clip
エクスプローラ上の全フォルダ/ファイルに対して、コンテキストメニューに追加するならば、下記をUTF-16 BOM有、CR+LFのテキストとして、拡張子regのファイルに保存し、(管理者として)実行すればよいです。
(要注意:下記の場合、キー「EzCopyPath」が既存だと、キーの内容を上書きしてしまうかと思います)
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\EzCopyPath]
@="EzCopyPath(&Z)"
[HKEY_CLASSES_ROOT\*\shell\EzCopyPath\command]
@="cmd /c set /p <NUL=\"<file://%1>\" | clip"
[HKEY_CLASSES_ROOT\folder\shell\EzCopyPath]
@="EzCopyPath(&Z)"
[HKEY_CLASSES_ROOT\folder\shell\EzCopyPath\command]
@="cmd /c set /p <NUL=\"<file://%1>\" | clip"
メニュー文言・ショートカットキーの部分は、好きに変えてください。
ダブルクォーテーション(拡張子regのファイル上は\"
)で囲まれた中の文字列を変えれば、ExcelのHYPERLINK関数に合わせることも可能です。
DOSコマンド詳細
- set
- /pオプションは本来、ユーザー入力を変数に代入。(今回は代入先となる変数を省略)
- NULを入力してあげることで、ユーザー入力を終わらせる。
- /pオプションでの右辺は、ユーザーへの表示メッセージだが、ダブルクォーテーションで囲むために好きな文字を書ける。しかも、表示の時にはダブルクォーテーションが消える。
- clip
- パイプや入力リダイレクトで渡した文字列をクリップボードに入れる。
終わりに
発展形として、割当てドライブをUNCパスに変換(例:H:\
>> \\Hoge\
)するもの、ファイルに対して以下のような2行を取得するもの、も作りました。
<file://[親フォルダへのパス]>
[右クリックされたファイル]
ご要望があれば、展開させていただきたいと思います。
追記(2022/3/16)
ご要望いただいたので、発展形を展開させていただこうと思います。
- 作った自分が若干忘れているので、以下の機能が全部載せから、下手に触れないです。
- 割当てドライブをUNCパスに変換(例:
H:\
>>\\Hoge\
) - 右クリックしたファイル/フォルダに対して、
<file://[親フォルダへのパス]\>\n[ファイル/フォルダ名]
取得 - 取得後、同じ階層のファイル/フォルダに対して右クリックしていくと、
\n[ファイル/フォルダ名]
付け足し可能
- 割当てドライブをUNCパスに変換(例:
regファイルにすると、こちら。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\*\shell\EzCopyPathIE_UNC]
@="EzCopyPath項目列挙 - UNCパス変換(&I)"
[HKEY_CLASSES_ROOT\*\shell\EzCopyPathIE_UNC\command]
@="cmd /c for /f \"tokens=*\" %%f in ('echo.\"%1\"') do (powershell -command \"$ErrorActionPreference = 'silentlycontinue'; Add-Type -Assembly System.Windows.Forms; $dat = [Windows.Forms.Clipboard]::GetText(); $src = \\\"%%~dpf\\\\\"; $unc = (Get-WMIObject -query 'Select * From Win32_LogicalDisk Where DeviceID=\\\"%%~df\\\" and DriveType = 4').ProviderName; if ($unc -ne $null) {$src = join-path $unc (split-path $src -NoQualifier)}; if (($dat.Contains($src + '>')) -And ($dat -match '>\\r\\n[^\\r\\n]')) {$out = $dat;} else {$out = \\\"^<file://$src^>`r`n\\\";}; $out += \\\"%%~nxf\\\"; write \\\"$out\\\";\" | clip)"
[HKEY_CLASSES_ROOT\Folder\shell\EzCopyPathIE_UNC]
@="EzCopyPath項目列挙 - UNCパス変換(&I)"
[HKEY_CLASSES_ROOT\Folder\shell\EzCopyPathIE_UNC\command]
@="cmd /c for /f \"tokens=*\" %%f in ('echo.\"%1\"') do (powershell -command \"$ErrorActionPreference = 'silentlycontinue'; Add-Type -Assembly System.Windows.Forms; $dat = [Windows.Forms.Clipboard]::GetText(); $src = \\\"%%~dpf\\\\\"; $unc = (Get-WMIObject -query 'Select * From Win32_LogicalDisk Where DeviceID=\\\"%%~df\\\" and DriveType = 4').ProviderName; if ($unc -ne $null) {$src = join-path $unc (split-path $src -NoQualifier)}; if (($dat.Contains($src + '>')) -And ($dat -match '>\\r\\n[^\\r\\n]')) {$out = $dat;} else {$out = \\\"^<file://$src^>`r`n\\\";}; $out += \\\"%%~nxf\\\"; write \\\"$out\\\";\" | clip)"
とても長い、command部分は改行やインデントを入れると、こうなっています。
cmd /c for /f "tokens=*" %%f in ('echo."%1"') do (
powershell -command "
$ErrorActionPreference = 'silentlycontinue';
Add-Type -Assembly System.Windows.Forms;
$dat = [Windows.Forms.Clipboard]::GetText();
$src = \"%%~dpf\\";
$unc = (Get-WMIObject -query 'Select * From Win32_LogicalDisk Where DeviceID=\"%%~df\" and DriveType = 4').ProviderName;
if ($unc -ne $null) {$src = join-path $unc (split-path $src -NoQualifier)};
if (($dat.Contains($src + '>')) -And ($dat -match '>\r\n[^\r\n]')) {
$out = $dat;
} else {
$out = \"^<file://$src^>`r`n\";
};
$out += \"%%~nxf\";
write \"$out\";
" | clip
)