[VBScript]クリップボードに入っているURLのデコード

# はじめに
Chromeって、URLをコピーすると、エンコードされますよね。
あれをそのままメールやチャットに貼られると、とりあえずリンク先を見てみないことには、何があるか分からないので、少し不親切な気がするのです。
（もちろん、前後の文脈で分かることは、非常に多いのですが・・・）

下記みたいに書かれるよりは、
[&lt;https://www.amazon.co.jp/%E3%83%96%E3%82%AE%E3%83%BC%E3%83%9D%E3%83%83%E3%83%97%E3%81%AF%E7%AC%91%E3%82%8F%E3%81%AA%E3%81%84-%E9%9B%BB%E6%92%83%E6%96%87%E5%BA%AB-%E4%B8%8A%E9%81%A0%E9%87%8E-%E6%B5%A9%E5%B9%B3/dp/4048694448/&gt;](https://www.amazon.co.jp/%E3%83%96%E3%82%AE%E3%83%BC%E3%83%9D%E3%83%83%E3%83%97%E3%81%AF%E7%AC%91%E3%82%8F%E3%81%AA%E3%81%84-%E9%9B%BB%E6%92%83%E6%96%87%E5%BA%AB-%E4%B8%8A%E9%81%A0%E9%87%8E-%E6%B5%A9%E5%B9%B3/dp/4048694448/)

下記みたいに書かれると、リンク先が分かって嬉しくないですか？
[&lt;https://www.amazon.co.jp/ブギーポップは笑わない-電撃文庫-上遠野-浩平/dp/4048694448/&gt;](https://www.amazon.co.jp/ブギーポップは笑わない-電撃文庫-上遠野-浩平/dp/4048694448/)

ということで、タイトル通りのスクリプトを作ってみました。

参考にしたWebサイトと、その理由を示しておきます。

- [WSHでIEを使わずにクリップボードを操作](https://masayoshi-9a7ee.hatenablog.com/entry/20141213/1418459994)
	- クリップボードから文字列を取得したい
- [WScript.ShellのExec()でコンソールアプリを非表示で実行する。その２](http://scripting.cocolog-nifty.com/blog/2007/05/wscriptshellexe_c7ec.html)
	- クリップボードへの文字列設定でDOSコマンドを使うが、DOS窓を見せたくない
- [64ビット環境でのScriptControlの代わり](http://www.ka-net.org/office/of32.html)
	- VBScript上でURLデコードしたい（上記サイトではエンコードですが）

# 作ったスクリプト
以下です。

```vb:[任意名称].vbs
Option Explicit

Const CON_SCRIPTHOST = "cscript.exe"
Const WIN_SCRIPTHOST = "wscript.exe"
Const CMD_SET_CLIPBOARD = "clip.exe"

Const CLASSNAME_FSO = "Scripting.FileSystemObject"
Const CLASSNAME_HTML = "HTMLFile"
Const CLASSNAME_SHELL = "WScript.Shell"
Const ForReading = 1, ForWriting = 2, ForAppending = 8

Dim fso
Dim html
Dim shell
Set fso = CreateObject(CLASSNAME_FSO)
Set html = CreateObject(CLASSNAME_HTML)
Set shell = CreateObject(CLASSNAME_SHELL)

Dim scriptBaseName
Dim scriptFolder
scriptBaseName = fso.GetBaseName(WScript.ScriptFullName)
scriptFolder = Left( _
	WScript.ScriptFullName, _
	Len(WScript.ScriptFullName) - Len(WScript.ScriptName))

Call HideExec()

Sub HideExec()
	Dim arg
	Dim args
	
	'// エクスプローラからの起動を確認
	If (LCase(Right(WScript.FullName, 11)) = WIN_SCRIPTHOST) Then
		args = Array(CON_SCRIPTHOST, """" & WScript.ScriptFullName & """")
		
		For Each arg In WScript.Arguments
			ReDim Preserve args(UBound(args) + 1)
			args(UBound(args)) = """" & arg & """"
		Next
		
		'// 最小化ウィンドウで自身を呼び出し
		Call WScript.Quit(shell.Run(Join(args, " "), 7, True))
	Else
		'// 最小化ウィンドウでメインの処理を実行
		Call Main()
	End If
End Sub

Sub Main()
	On Error Resume Next
	
	Dim contents
	contents = DecodeClipBoardText()
	
	If (contents <> "") Then
		contents = vbNewLine + vbNewLine + "処理結果：" + vbNewLine + contents
	End If
	Call shell.Popup("処理を完了しました。" + contents, 5, scriptBaseName, vbInformation)
End Sub

Function DecodeClipBoardText()
	DecodeClipBoardText = ""
	
	Dim contents
	Dim dummyElement
	Dim exec
	
	'// クリップボード文字列取得
	contents = html.ParentWindow.ClipboardData.GetData("text")
	
	'// 文字列置換
	Set dummyElement = html.CreateElement("span")
	Call dummyElement.SetAttribute("id", "result")
	Call html.AppendChild(dummyElement)
	Call html.ParentWindow.ExecScript("document.getElementById('result').innerText = decodeURIComponent('" & contents & "');", "JScript")
	contents = dummyElement.InnerText
	
	'// クリップボード文字列設定
	Set exec = shell.Exec(CMD_SET_CLIPBOARD)
	Call exec.StdIn.Write(contents)
	Call exec.StdIn.Close()
	Call exec.StdOut.ReadAll()
	
	DecodeClipBoardText = contents
End Function
```

使う時は、URLをコピーした直後にスクリプトを起動する（vbsファイルをダブルクリックする）だけです。

# 終わりに
コンソールアプリを非表示で実行するというテクニックは、他にも使えそうです。
DOSコマンドの`findstr`（機能が弱くて残念だが、多少の正規表現が使えるgrep）を、テキストファイル各行に定義した検索文字列に対して、連続で実行するスクリプトとか、どうでしょうか。