CMD.exeでパス名に空白が入ってどうしても解決できないときのオカルト技

#通常の解決方法
##二重引用符で囲む
[VBScript でパスに空白を含むアプリケーションを起動するときには、二重引用符を 2 つ続ける ](http://jutememo.blogspot.jp/2014/03/vbscript-2.html)

```vbnet
CreateObject("WScript.Shell").Run """C:\Program Files (x86)\LibreOffice 4\program\soffice.exe"""
```
##DIr /Xでショートパスを見つける
[Windows でパスに空白を含むときの回避策](http://garapon.hatenablog.com/entry/20080124/1201149409)

`C:\Program Files\Microsoft Office\root\Office16\1041\QuickStyles`
`C:\Program Files\\Microsoft Office\\root\Office16\1041\QuickStyles`
のとき

```vb
Dir c:\ /X
```

から順に見つけると
`C:\Progra~1\MICROS~3\root\Office16\1041\QUICKS~1`
だとわかる
しかしこの方法はフォルダが下になるほど見つけるのが面倒。

#しかしそれでもダメな場合
###ダメもとで\を二重にする
####Robocopy
Zがネットワークドライブとする。
たとえば`E:\` `Z:\10 hoge\`にロボコピーをする
`Robocopy "E:\\"  "Z:\\10 hoge\" "*.*" /COPY:DAT`
####mkDir,rmDirで使う(2020/09/18追加)
これはどうなるか
<pre>
E:&yen;tt&yen;t&nbsp;t&yen;
</Pre>
<pre>mkdir "E:&yen;tt&yen;&yen;t&nbsp;t&yen;&yen;"</Pre>

<pre>mkdir "E:&yen;tt&yen;&yen;t&nbsp;t&yen;&yen;a a&yen;&yen;"</Pre>

<pre>mkdir "E:&yen;a a&yen;&yen;s&nbsp;s&yen;&yen;t&yen;"</pre>

空白が入った場合、その直後の&yen;を二重にする
このため上記のフォルダを削除するときは
<pre>rmDir "E:&yen;a&nbsp;a&yen;&yen;" /s</pre>
このDirectoryを削除するときはa&nbsp;aが空白が入っているので次の&yen;は2つになる。
二重引用符は一つで良い。

####Win+R「ファイル名を指定して実行」でcmdからmkDirをすると違う(2020/09/18追加)
コマンドプロンプトの黒い画面では&yen;&yen;は有効だが、Cmdから起動すると二重にしてもしなくてもよいが、空白をダブルクォーテーションで囲む&yen;&yen;というオカルト技が通じず、ディレクトリの文字列の途中にある空白は`" "`としなければならない。

```powershell:CMD
%Comspec% /k "mkdir ""E:\tt\\t" "t\\a" "a\\"""
```

:ball:これは＆yen;は一つでも良い

```powershell:CMD
%Comspec% /k "mkdir ""E:\tt\t" "t\a" "a\"""
```


####Win+R「ファイル名を指定して実行」でcmdからrmDirのようにオプションスィッチを後置するとき

```powershell:CMD
%Comspec% /k "rmdir ""E:\tt"" /s /q"
```

##UNCパス形式の場合
`\\ServerDirve0001-1\dir\10 hoge\`
のような場合二重にするのは二番目
`\\ServerDirve0001-1****\\****dir\10 hoge\`
`\\ServerDirve0001-1\\dir\10 hoge\`

```powershell:CMD
Robocopy "E:\\"  "\\ServerDirve0001-1\\dir\10 hoge\" "*.*" /COPY:DAT
```

##原因
[Windowsパス名の落とし穴 ](https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b08_01.html)
のディレクトリ階層の落とし穴
Windowsには補完する機能や自由度があるのが原因。

入力させたパス名をプログラム中で使用するときは注意が必要である。ディレクトリ区切り文字に「\」と「/」の両方が混在・重複しても許されたり，ロングネームとショートネームが存在するなど，複雑な事情がある。 
`d:\\InetPub\\\wwwroot\\\\secret\\\\\data.txt`
　ディレクトリの区切り文字は幾つか重複しても構わない（ただしスペースがあるとだめ）。日本語環境では円マークで表示される
`d:////InetPub///wwwroot//secret/data.txt`
　半角の「/」も重複できるし、これでディレクトリを表すことができる。
これとバグの表記をみると
 hoge\ドライブはありません。という風に上が欠落している。つまりスペースの前がなくなる。
円マーク（バックスラッシュ）が二重になることで、一種のエスケープ状態になるようだ。
たしかに
`Dir C:\\` はエラーだが

```Powershell:CMD
Dir "C:\Program Files\\Microsoft Office\\Office16\\"
```

これは有効だ。
この方法はバグで出されるエラーを見ながらバックスラッシュ、円マークを増やすとよい。
上記のフォルダはDir命令は

```Powershell:CMD
Dir "C:\Program Files\\Microsoft Office\\root\Office16\1041\QuickStyles
```

最後になぜか二重引用符`"`は要らない。入れるとエラーになる。しかし二重引用符がないとオプションスィッチをつけることができない。どうしたらよいだろうか。解決策が下の通り。

```Powershell:CMD
Dir "C:\Program Files\\Microsoft Office\root\Office16\1041\QuickStyles" /a-d
```

とこのようにMicrosoft　Officeの後ろの\\\を\にするとオプションスィッチが使える。
エラーを見ながら決めていくのでオカルトとしか言いようがないが。

#環境変数を使う（補足）
もちろん、環境変数を使うのも有効だ。

```Powershell:CMD
Dir "%Programfiles(x86)%\\\\\"
```
もありだし

```Powershell:CMD
Dir "%PROGRAMFILES(X86)%////"
```

こんな表記も有効だ。特にProgramFiles、Common Filesフォルダ、Set命令で環境変数をから抜粋すると

```powershell:CMD
%CommonProgramFiles%=C:\Program Files\Common Files
%CommonProgramFiles(x86)%=C:\Program Files (x86)\
%CommonProgramW6432%=C:\Program Files\Common Files
```

これは2つも空白があるため、非常に有効に空白を回避できる。
%CommonProgramW6432%は64bitでも32でもメインのcommon filesを指す「共通Common Filesフォルダ」となる。互換性を重視するときはこちらを使う。
欠点は今環境変数を好き勝手に設定するのはどうかという点であろう。任意に環境変数で空白を回避してもその設定でしか動かないためだ。

#omake
[Poweshellは空白の前にエスケープすればよい](https://social.technet.microsoft.com/Forums/ja-JP/29918073-43cf-4e24-8bce-b4090c05c2d4?forum=powershellja)
回答者は牟田口氏である。
[C#質問：ネットワークドライブからＵＮＣパスを取得する方法](https://social.msdn.microsoft.com/Forums/vstudio/ja-JP/b33ff797-be1e-4a3b-9cd7-d4565529783f?forum=csharpgeneralja%5D)
回答者はDobon.netのじゃんぬ氏である。