windows」タグアーカイブ

Lua スクリプトと Windows のバッチファイルを同じファイルに同居させる

スクリプト言語で書いたプログラムをシェルコマンドとして実行したい時、 Unix の場合は shebang と呼ばれる行を書けば良い。

しかし、 Windows のコマンドインタープリター (cmd.exe) の場合はそういう風にはいかない。代わりに、バッチファイル (.bat) なり、バイナリの実行ファイル (.exe) を用意して、その中でスクリプト言語のインタープリターを呼び出す、という手法を使うことになる。

この場合、配布するファイルがバッチファイルと実行したいスクリプトファイルの2つになり、単独の実行ファイルを配布する場合に比べて2倍面倒である。1つのファイルを、バッチファイルとしてもスクリプトファイルとしても実行できれば良いのではないか。(このような、複数のプログラミング言語で解釈できるプログラムを polyglot と呼ぶことがあるようだ)

今回、対象とするスクリプト言語は Lua である。Lua スクリプトとバッチファイルの双方として実行可能なファイルを作りたい。 続きを読む

Picked up JAVA_TOOL_OPTIONS: を擬似的に消す

昔話

その昔、Mac OS X で java コマンドを起動するとターミナルが UTF-8 であってもメッセージがシフトJISで出力されて文字化けしてしまうという時代があった。

java コマンドの起動時に -Dfile.encoding=UTF-8 をつければ出力が UTF-8 になるが、毎回指定するのは面倒くさい。

そんな時、人々は JAVA_TOOL_OPTIONS という環境変数を -Dfile.encoding=UTF-8 に設定したものだ。

そうすれば、確かにメッセージは UTF-8 で出力される。されるのだが…。

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8

という余計なメッセージまで出力される。うるさい。

…というのは過去の話で、最近の Java を Mac 環境で使う分には JAVA_TOOL_OPTIONS を指定しなくても出力が UTF-8 になるので、特に問題はない。(確か、環境変数 LANG を読むはず)

2016年の話

残念なことだが、2016年にもなって、コマンドライン環境で UTF-8 以外のマルチバイトエンコーディング(シフトJISとか)が広く使われている環境が存在する。そういう環境に UTF-8 なターミナル(MinTTY とか)を用意してやっても、デフォルトでは java はシフトJISでメッセージを吐いてくる。したがって、そういう環境で java コマンドのメッセージの出力を UTF-8 にしたい場合は、 JAVA_TOOL_OPTIONS-Dfile.encoding=UTF-8 を指定する必要がある。

まあ、 UTF-8 以外のマルチバイトエンコーディングが広く使われている環境が存在するのは仕方がない。受け入れるしかない。しかし、Picked up JAVA_TOOL_OPTIONS: が出てくるのはなんとかしたい。

このメッセージの出力を抑制できないならば、せめて「見えないように」する方法があるのではないか。つまり、 Picked up JAVA_TOOL_OPTIONS: が印字された後に、空白文字で上書きする…!

つまり、こうだ:

JAVA_TOOL_OPTIONS=$'\r-Dfile.encoding=UTF-8\r                            \r'

$'ほにゃらら' というのは、 bash にエスケープ文字を解釈させる文法だ。この記事に関心を持つような人ならば何をやっているか分かるだろう。

キャリッジリターンとか言ってないで ANSI escape を駆使すれば空行すらなくせるかもしれないが、残念ながらそういうのはキャリッジリターン \r と違い、オプション解釈の際に空白として読み飛ばされない。

真面目な話

ドヤ顔でキャリッジリターンとか書いてみたものの、実際に使ってみると表示が崩れる場合が散見されるので、常用するのはやめたほうがよさそうである。

総合的に考えると、次のようなシェル関数を書いて対応するのがベストかと思われる。(シェルで単独で java を叩いた場合は Picked up … が表示されず、間接的に起動された場合は Picked up … が表示される。)あるいは、シェルスクリプトでラップしてやるという手も考えられる。

export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
function java() {
    env JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS/-Dfile.encoding=UTF-8/}" java -Df
ile.encoding=UTF-8 "$@"
}
function javac() {
    env JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS/-Dfile.encoding=UTF-8/}" "${JDK_P
ATH}/javac" -J-Dfile.encoding=UTF-8 "$@"
}

何をやっているかというと、 java という名前のシェル関数で、「環境変数 JAVA_TOOL_OPTIONS から “-Dfile.encoding=UTF-8” という文字列を削除」「java コマンドに -Dfile.encoding=UTF-8 オプションを渡す」ということをやっている。bash 以外のシェルでは違う書き方が必要になるだろう。

余談

余談だが、ドットネット系のプログラムは、コマンドプロンプトで chcp 65001 をすると出力が UTF-8 になるようだ。UTF-8 なターミナルから MSBuild とか csc とかを叩くときに覚えておくと良いだろう。(Windows の Java も GetConsoleOutputCP で出力文字コードを判断してくれれば良かったのだが…)

Windows で JDK のインストール先を取得

Windows に JDK を入れた時のインスートル先のディレクトリというのは、バージョンによって変わる。これを機械的に取得したい。

環境変数の類は設定されない(公式のマニュアルに、手動で設定する方法が書かれてるくらいだし)ようだが、レジストリを見ればパスを取得できる。

Stack Overflow の質問には reg コマンドを使った回答が付いているが、Windows の場合こういうのはバッチファイルで書くよりも WSH を使った方が文字列処理等がすっきりするだろう。

というわけで書いてみた。

var WshShell = WScript.CreateObject("WScript.Shell");
var JDKKey = "HKLM\\SOFTWARE\\JavaSoft\\Java Development Kit\\";
var CurrentVersion = WshShell.RegRead(JDKKey + "CurrentVersion");
var JavaHome = WshShell.RegRead(JDKKey + CurrentVersion + "\\JavaHome");
var JDKBin = JavaHome + "\\bin";
WScript.Echo(JDKBin);

このファイルを例えば showjdkpath.js という名前で保存して、 CScript /nologo showjdkpath.js と実行すれば、標準出力に javac の場所が出てくる。

MSYS2 から Visual C++ (の環境変数を設定するバッチファイル)を叩く

2016年4月26日:「シェルでやる方法」を追記。

Windowsの開発環境には、環境変数を設定するバッチファイルが提供されていて、そのバッチファイルを実行すると PATH とかの環境変数が設定されるというパターンがたまにある。(スタートメニューに「環境変数を設定済みのシェルを起動する」ショートカットを登録するパターンの方がもっと多い気がするが)

MSYS2からこういう開発環境(というか、Visual C++)を叩きたい。もちろん、cmd.exe を使って

$ cmd //c "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"

みたいなことをすれば vcvars64.bat (Visual C++用に環境変数を設定するバッチファイル)を実行すること自体はできるが、そこで設定された環境変数は呼び出し元のシェルに反映されない。 続きを読む

タブレット端末からのリモートデスクトップでWindowsのタッチ操作を試す

最近のWindowsはタッチ操作に対応している。が、タッチに対応したディスプレイなんて持っておらず、わざわざ買うほど必要性も感じない。そういう場合に、iOS/Android端末と、リモートデスクトップ接続を受け付けることができるWindowsを持っていると、Windowsのタッチ操作を試せる。

今回のWindows 8.1を買う前の下調べで、(無印とProの違いの一つである)Windowsのリモートデスクトップ機能についてググっていたところ、「iOS/AndroidタブレットからリモートデスクトップでWindowsにつなぐと、タッチ操作ができる」という情報を見かけた(このへん)。そういうことなら、リモートデスクトップができるPro版を買うしかない。と思って、無印よりも数千円高いPro版のWindows 8.1を買ったのだった。

以下、iPadからリモートデスクトップでWindows機を操作するまでの手順。

Windowsの設定でリモートデスクトップを有効にする

コントロールパネルで
システムとセキュリティ > システム > リモートアクセスの許可
とクリック。
remotedesktop-step1

リモートデスクトップのオプションで、「このコンピューターへのリモート接続を許可する」をクリック。
remotedesktop-step2

なんかメッセージが出るので「OK」を押す。
remotedesktop-step3

これで、リモートデスクトップが有効になった。
remotedesktop-step4

iOS端末/Android端末にMicrosoft純正のリモートデスクトップクライアントを入れる

インストールが終わったら、起動して適当に設定してやる。

遊ぶ

リモートデスクトップでつなぐと、画面サイズはクライアント側で指定したものになる。iPadからつなげばiPadの画面サイズになる。画面の向きは、横向きで固定のようだ。

「コンピューターの基本的な情報の表示」を見ると、「ペンとタッチ」の項目は「10タッチポイントでのタッチ(制限あり)のサポート」となっている。「制限あり」とあるがどこが制限されているのかはよく分からない。
IMG_0065

みんな大好きな「ペイント」では、ブラシツールを使って複数点同時に描くことができるようだ。IMG_0066

自作PCにWindows 8.1を導入した (2)

前回: 自作PCにWindows 8.1を導入した

Arch LinuxとWindowsのデュアルブート

自分がArch Linuxを入れる時に使ったブートマネージャーはrEFIndだった。そのコンピューターに追加でWindowsを入れると、Windows Boot Managerがハードディスクのどこかにインストールされてそれが使われるようになる。が、それだと起動時にOSを選択できないので、ブートマネージャーの選択をrEFIndに戻す。ブートマネージャーを選ぶには、ファームウエア(UEFI?)の側でブートデバイスを選ぶ要領でやればよい。自分が使っているGIGABYTEのマザーボードだと、電源投入直後にF12を押すとブートデバイスを選択する画面が出るので、そこでrEFIndを選択した。

rEFIndの画面には、起動できるOS(今は2種類。OSのインストールDVDを入れるとそれも選択肢に現れる)の一覧が表示されるので、それで選べばよい。

ハードウエアクロック

Arch Linuxをインストールした時、ハードウエアクロックはUTCで設定したが、Windowsではデフォルトで地方時(local time)を使う(?)ので、日本だと9時間ずれた時間がWindows上に表示される。

この問題については、Arch Wikiの記事に書いてある(日本語記事)。記事に従ってレジストリをいじればよい。Windowsによる時刻同期は、よくわからないが切った方がいいらしい。

ソフトウエアのインストール

コマンドラインで使えるWindows向けのパッケージマネージャーであるところのChocolateyを入れてみた。そうすると、管理者権限のあるコマンドプロンプトとかPowerShell上で

choco install virtualbox
choco install GoogleChrome
choco install gimp

という具合でソフトウエアを導入できる。便利。

デュアルブートじゃなくて仮想化で同時に使いたい

先に書いたように、起動時にWindowsかArch Linuxかを選択すれば、どちらか一方のOSを起動できる(デュアルブート)。が、時代は仮想化だ(?)。Windowsを立ち上げつつLinuxも使う、あるいはその逆をやりたい。それも、新しく仮想マシンにLinuxをインストールするのではなく、既に物理ハードディスクにインストールしてあるLinuxを使いたい。

普通、仮想化ソフトウエアでOSを動かすときは、ゲストOS用のハードディスクの実体はホストOSのファイルシステム上に作られる数十GBのファイルになっているが、その代わりに物理ハードディスクを直接ゲストOSに割り当てたい。

VirtualBoxの場合はこの辺の手順でそれができるらしい。が、なぜかうまくいかなかった。どういうエラーが出たかは覚えていない。

そういえば今回インストールしたのは8.1 Pro (x64)なので、Hyper-Vというやつが使えるはずだ。試してみようということで、
コントロールパネル > プログラム > プログラムと機能 > Windows の機能の有効化または無効化
でHyper-Vにチェックを入れ、再起動。この辺の記事を参考に設定しようとしたが、物理ディスクをオフラインにする手順のところで詰まった。具体的には、
コンピューターの管理 > 記憶域 > ディスクの管理
で、Arch Linuxが入っているディスク0をオフラインにしようとしたら、「現在のシステムディスクまたは BIOS ディスク 0 上のディスク属性は変更できません。 」というエラーが出た。EFIが入っているディスクだからダメなのか。よくわからん。

続きはまた今度。