ちょっと作ってみたツール

SEを10年くらいやっていました。あったら便利だなーってツールを書いています

Windows10でピクチャっぽいことをする

Windows10にはピクチャアプリケーションがなくて画像を連続で見るときに不便です。

使い方

見たい画像やファイルを下記のファイルにドラッグアンドドロップします。 「送る」に格納してもよいかもしれません

ソース

var fso = new ActiveXObject("Scripting.FileSystemObject");
var ie = WScript.CreateObject("InternetExplorer.Application", "IE_");
var objshell = new ActiveXObject("shell.application");
var shell = WScript.CreateObject("WScript.Shell");

/* store current folder item's path */
var info = [];
/* position of showing image */
var position = 0;

init();
fileOpen(fso.GetAbsolutePathName(WScript.arguments.Item(0)));
focus();

while(true) {
    WScript.Sleep(1000);
}

// create page image
function init() {
    ie.Visible = true;
    ie.Navigate("about:blank");

    var img = ie.Document.createElement("img");
    var text = ie.Document.createElement("div");
    var title = ie.Document.createElement("div");
    var video = ie.Document.createElement("video");

    ie.Document.body.appendChild(title);
    title.id = "title";
    title.style.cssText = "width:100%; text-align:center; display:block";

    ie.Document.body.appendChild(text);
    text.id = "text";
    text.style.cssText = "border: 1px solid black;";
    text.addEventListener("mouseDown", openByApp);

    ie.Document.body.appendChild(img);
    img.id = "img";
    img.style.cssText = "display:block; margin:auto ";
    img.addEventListener("mouseDown", openByApp);

    ie.Document.body.appendChild(video);
    video.id = "video";
    video.style.cssText = "margin: auto";

    /* set actions of keydown */
    ie.Document.addEventListener("keydown", function(e) {
        // left allow
        if (e.keyCode == 37) {
            position = position - 1 >= 0 ? position - 1 : info.length - 1;
            show(info[position]);
        // up allow
        } else if (e.keyCode == 38) {
            fileOpen(fso.GetParentFolderName(info[position]['path']));
        // right allow
        } else if (e.keyCode == 39) {
            position = position + 1 < info.length ? position + 1 : 0;
            show(info[position]);
        // down allow
        } else if (e.keyCode == 40) {
            if ( info[position]['type'] == 'folder' ) {
                folderOpen(info[position]['path']);
            }
        // space key
        } else if (e.keyCode == 32) {
            openByApp();
        }
    });
}

function focus() {
    var ie_list = [];
    /* get root IE process and focus it */
    for ( var e = new Enumerator(GetObject("winmgmts:").InstancesOf("Win32_Process"));
        !e.atEnd(); e.moveNext()) {
        var p = e.item();
        /* app activate and creation date of ie which recently activate */
        if ( p.Name == "iexplore.exe") {
            ie_list.push( {
                'pid':  p.ProcessId,
                'ppid': p.ParentProcessId
            });
        }
    }
    var process = ie_list[0];
    for ( var i = 0; i < ie_list.length; i++) {
        if ( process['ppid'] == ie_list['pid'] ) {
            i = 0;
        }
    }
    shell.AppActivate(process['pid']);
    ie.Document.focus();
}

function folderOpen(target) {
    setInfo(target);
    setPosition(info[0]['path']);
    show(info[position]);
}

function fileOpen(target) {
    setInfo(fso.GetParentFolderName(target));
    setPosition(target);
    show(info[position]);
}

function setInfo(target) {
    info = getItems("folder", fso.GetFolder(target).SubFolders);
    var files = getItems("file",   fso.GetFolder(target).Files);
    for ( var i = 0; i < files.length; i++) {
        info.push(files[i]);
    }
}

function getItems(type, list) {
    var ret = [];
    for ( var e = new Enumerator(list); !e.atEnd(); e.moveNext()) {
        ret.push({'type': type, 'path':e.item().Path});
    }
    return ret;
}


function setPosition(path) {
    for (var i = 0; i < info.length; i++) {
        if (info[i]['path'] == path) {
            position = i;
        }
    }
}

/* procedure show item */
function show(item) {
    var path = item['path'];
    var img = ie.Document.getElementById('img');
    var title = ie.Document.getElementById('title');
    var text = ie.Document.getElementById('text');
    var video = ie.Document.getElementById('video');

    /* at first, undisplay all */
    text.style.display  = "none";
    img.style.display  = "none";
    video.style.display  = "none";

    title.innerText = path;
    if ( item['type'] == 'folder') {
        text.innerText = "[Folder]";
        text.style.display = "block";
    } else {
        if ( fso.GetExtensionName(path).match(/(png|jpg|jpeg|gif|bmp|heic|heif|jp2|j2c|webp|tiff|tif|svg|svgz)/i)) {
            img.src = path;
            resize(img, title);
            
            img.style.display  = "block";
        } else if (fso.GetExtensionName(path).match(/mp4|webm|ogg/i)) {
            video.src = path;
            resize(video, title);
            video.style.display  = "block";
        } else if (fso.GetExtensionName(path).match(/txt/i)) {
            var fh;
            try {
                fh = fso.OpenTextFile(path);
                text.innerText = fh.ReadAll();
                text.style.display = "block";;
            } finally {
                if ( fh != null) { fh.Close(); }
            }
        } else {
            text.innerText = "[unablable to display]";
            text.style.display = "block";
        }
    }
}

function openByApp(e) {
    var path = info[position]['path'];
    if ( fso.GetExtensionName(path).match(/(png|jpg|jpeg|gif|bmp|heic|heif|jp2|j2c|webp|tiff|tif|svg|svgz)/i)) {
        shell.run("mspaint.exe \"" + info[position]['path'] + "\"");
    } else if (fso.GetExtensionName(path).match(/txt/i)) {
        shell.run("notepad.exe \"" + info[position]['path'] + "\"");
    }
}

/* resize e(lement) size to fix window */
function resize(e, title) {
    if (e.naturalWidth < ie.Document.body.clientWidth && e.naturalHeight < ie.Document.body.clientHeight) {
        e.style.height = e.naturalHeight;
        e.style.width =  e.naturalWidth;
    } else {
        var height_ratio = (ie.Document.body.clientHeight - title.clientHeight - title.offsetTop * 2 - 2) / e.naturalHeight;
        var width_ratio  = ie.Document.body.clientWidth / e.naturalWidth;
        if ( height_ratio < width_ratio) {
            e.style.height = e.naturalHeight * height_ratio;
            e.style.width =  e.naturalWidth  * height_ratio;
        } else {
            e.style.height = e.naturalHeight * width_ratio;
            e.style.width =  e.naturalWidth  * width_ratio;
        }
    }
    
    e.style.display  = "block";
}

/* Quit self, when IE quit */
function IE_OnQuit() {
    WScript.Quit();
}

fileviewer wsh

C#のファイルをコンパイルするバッチ

お題「愛用しているもの」

C#のファイルで1ファイルしかないものを作るときに愛用しています。

そんなに使わないけど。ファイルのドラッグアンドドロップでもコンパイルできます。

使い方

(後述のソースをcscompiler.batとします)

cscompiler.bat test.cs
->同じフォルダにtest.exeが作成されます

ソース

SETLOCAL
IF "%1" == "" (
    echo ファイルを指定してください
    exit /b
)

REM 使っている環境で最新の.NET環境を検索
IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v4.0.30319" (
    SET COMPILER=%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\csc.exe
    SET REFERENCE=/reference:PresentationCore.dll /reference:PresentationFramework.dll /reference:WindowsBase.dll
) ELSE IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v3.5" (
    SET COMPILER=%SystemRoot%\Microsoft.NET\Framework\v3.5\csc.exe
    SET REFERENCE=/reference:PresentationCore.dll /reference:PresentationFramework.dll /reference:WindowsBase.dll
) ELSE IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v3.0" (
    SET COMPILER=%SystemRoot%\Microsoft.NET\Framework\v3.0\csc.exe
) ELSE IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v2.0.50727" (
    SET COMPILER=%SystemRoot%\Microsoft.NET\Framework\v2.0.507\csc.exe
) ELSE IF EXIST "%SystemRoot%\Microsoft.NET\Framework\v1.1.4322" (
    SET COMPILER=%SystemRoot%\Microsoft.NET\Framework\v1.1.4322\csc.exe
ELSE (
    EXIT /B
)

"%COMPILER%" /out:"%~dpn1.exe" %*
ENDLOCAL

固定長の長さの数値を使いまわすバッチ

頑張った割には糞どうでもいいものがあったりするものがあります。

使い方

(ここでは後述のソースをnumbered.batで保存したとします) 大域変数にバッチ名の変数名で数字を保存します。 バッチを呼び出される度にデータがカウントアップします

サンプル

numbered.bat 4 echo {}
0000
numbered.bat 4 echo {}
0001
REM ファイルの古い順に(4ケタの数字).datというファイル名でリネームします
for /F %i in ('dir /OD /B') DO numbered.bat 4 MOVE "%i" {}.dat

ソース

@ECHO OFF
SETLOCAL EnableDelayedExpansion

CALL :COUNT
ENDLOCAL
@ECHO ON

@REM 大域環境変数にぶっこむ
@SET "%~nx0=%ERRORLEVEL%"

@ECHO OFF
SETLOCAL EnableDelayedExpansion

REM ゼロパディング作成
FOR /L %%i in (1,1,%1) DO SET ZEROS=0!ZEROS!

REM 大域変数から値を再取得。パディングした文字列とくっつけ、指定の文字長分だけ取り出す
SET Y=!%~nx0!
SET Y=%ZEROS%%Y%
SET Y=!Y:~-%1,%1!

REM コマンド分を作成。最初の引数は扱わないようにFLAGでコントロール
SET FLAG=0
SET CMD=
FOR %%I IN (%*) DO IF !FLAG! == 0 (SET /A FLAG=1) ELSE (SET CMD=!CMD! %%I)
SET CMD=!CMD:{}=%Y%!

REM コマンド実行先頭に無駄なスペースが入っているので削除しておく
!CMD:~1!

ENDLOCAL
@ECHO ON
@goto :EOF

:COUNT

SET /A X="%~nx0=!%~nx0! + 1"
EXIT /B !X!

コマンドの実行を測る

PowerShellを使えば余裕なので

@powershell -c "Measure-Command {%*} | %% {echo $_.ToString() }"

最初っからPowerShell使えよって話なのですが、PowerShellレジストリいじらないと、外部ファイル呼び出せないから・・・

スクリーンセーバーを起動させないスクリプト

以前、はてブを見ていたら、こんなのがあり

togetter.com

その中に

というツイートを見たので、実装してみました

Set sh = CreateObject("WScript.Shell")

If WScript.arguments.Count = 0 Then
    sh.Run "cmd /K " & "cscript """ & WScript.ScriptFullName & """ 1", 1
Else
    While True
        sh.SendKeys "+"

        WScript.Sleep 60 * 1000
    Wend
End If

バッチで標準入力を取得する

どーでもえぐぜ

なにがしたいというわけではないのだけど、バッチコマンドの中で標準入力を取得する方法はないのかなと思っていたら。あった。

type C:\Windows\System32\drivers\etc\hosts | findstr ".*"
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#       127.0.0.1       localhost
#       ::1             localhost

なので、バッチの中で

@FOR /F "delims=" %%T IN ('FINDSTR ".*"') DO ...

とすればいいのか。