Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
27
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@y-takano

ショートカットを作成するバッチファイル(ファイル単体, JScript混在)

背景

 現場でバッチからショートカットが作れなくて困っていた。
 家に帰ってから作ってみたけど家では使い道がない…。でもせっかく作ったので記録しておく。

仕様概要:

 使おうとしていた環境はWindows7端末。
 バッチへPathが通っていることが前提条件。

使い方①:1行でデスクトップにショートカットを作成する

 ショートカットの動作:ダブルクリックするとただメモ帳が起動する

cmd
shortcut "%USERPROFILE%\Desktop\hogehoge.lnk" "C:Windows\notepad.exe"

使い方②:1行で「送る」にショートカットを作成する

 ショートカットの動作:右クリック->「送る」するとメモ帳で開く

cmd
shortcut "%USERPROFILE%\AppData\Roaming\Microsoft\Windows\SendTo\hogehoge.lnk" "C:Windows\notepad.exe"

とりあえずソース

 丸コピして保存すればすぐ使えるはず。

shortcut.bat
@if(0)==(0) echo off
cscript.exe //nologo //E:JScript "%~f0" %*
goto :EOF
@end

// メイン処理
function main() {
    var shortcut = null;
    try {
        // ショートカットを作成する
        shortcut = new ShortcutCreater();
        shortcut.create();

        // 作成したショートカットをコンソールに出力する
        Console.println("ショートカットを作成しました");
        Console.println(shortcut);

    } catch (e) {

        // 例外原因をコンソールに出力する
        Console.println("[error occured]: " + e.description);
        Console.println("usage: shortcut.bat [filepath] [linkpath]");

        // 異常終了でコマンドを返す
        Console.back(e.number);

    } finally {

        // WSHオブジェクトを片付ける
        if (shortcut !== null)
            shortcut.cleanup();
    }

    // 正常終了でコマンドを返す
    Console.back(0);
}

// コンソール汎用クラス
var Console = ((function() {
    var constructor = function() {}
    constructor.println = echoConsole;
    constructor.back = exitScript;
    return constructor;
})())

// ショートカットを作るクラス
var ShortcutCreater = function() {
    var args = WScript.Arguments;
    validate(args);
    this.wshObj = openWsh();
    this.file = args(0);
    this.link = args(1);
    this.create = createShortcut;
    this.cleanup = closeWsh;
    this.toString = createrToString;
}

// ----- 以降関数群 -------

function validate(args) {
    if (args == null) {
        throw new Error(1, "args=null or undefined");
    }
    if (args.length !== 2) {
        var str = "args = ";
        for (i=0; i < args.length; i++)
            str += "[" + i + "]:" + args(i) + " ";
        throw new Error(2, str);
    }
}

function createShortcut() {
    var lnkFile = this.wshObj.CreateShortcut(this.file);
    lnkFile.TargetPath = this.link;
    lnkFile.Save();
}

function createrToString() {
    return "file=\"" + this.file + "\", linkTo=\"" + this.link + "\"";
}

function openWsh() {
    return WScript.CreateObject("WScript.Shell");
}

function closeWsh() {
    this.wshObj = null;
}

function echoConsole(msg) {
    WScript.echo(msg);
}

function exitScript(errNum) {
    WScript.Quit(errNum);
}

// メイン処理呼び出し
main();

JScript部分については説明を割愛する。

おまじない

 この先頭4行がミソで、これ以降のソースはWSHのJScriptで書ける。

@if(0)==(0) echo off
cscript.exe //nologo //E:JScript "%~f0" %*
goto :EOF
@end

 正式な文法ではなく裏ワザ的なものみたいで、動作保証についてちょっと心配ですが、
 かなり昔から動いてるだろうし大丈夫かな、と個人的には思いました。
 いやあ、それにしても考えた人はすごいですね。

参考文献

 大変助かりました。ありがとうございました。

 BATとWSHのコードを1ファイルに混在させるためのshebang記法(複雑なバッチを1ファイルで実現)

 JScript でハマる日々

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
27
Help us understand the problem. What are the problem?