2015年4月28日火曜日

Wandbox が複数ファイル対応したので試してみた



Wandbox が複数ファイルに対応したようなので、早速試してみました。
iuwandbox
iuwandbox は私が作っている C++ テスティングフレームワーク iutest を Wandbox 使うためのツールです。
今回はこちらを複数ファイル対応しました。

以前の、iuwandbox では iutest の実装をすべて1つのファイルに展開し、実現していました。
Wandbox の複数ファイル対応によって、この展開が不要になります。
以前の iuwandbox については、Boost.勉強会の LT でもお話しましたので、そちらのスライドを参考にしてください。

ブログズミ: Boost.勉強会#16 大阪に行ってきました > 発表資料
ブログズミ: Shippable + Wandbox で C++ の CI 環境構築

Wandbox の複数ファイル対応にあたって、API に codes パラメータが追加されています。
https://github.com/melpon/wandbox/blob/master/kennel2/API.rst
codes には、file にファイル名を code に内容を書いて配列データとして追加します。
Wandbox の API に関わる部分だけ切り出して公開してますので、ご自由にお使い下さい。
https://github.com/srz-zumix/wandbox-api

続いて、iuwandbox 側の修正です。
これまでは #include "path/iutest.hpp" という(パスは何でも良い)行があったら、そこにコードを全展開していました。
これを iutest.hpp という別ファイルと #include "iutest.hpp" として処理するようにしました。
また、--expand_include オプションを指定しなかった場合に、対象のファイルも追加ファイルとして送るように修正しています。

こちらの修正は github から取得できます。
https://github.com/srz-zumix/iutest

サンプル
https://github.com/srz-zumix/iutest/tree/master/tools/wandbox
こちらにあるサンプルの実行結果が以下になります。

複数ファイル対応前の結果:http://melpon.org/wandbox/permlink/rxop0vcJGIrj9BwC
複数ファイル対応後の結果:http://melpon.org/wandbox/permlink/HTCDKqWvJ8TlvmUa
※対応前のリンクは開くのに時間がかかるので注意!

複数ファイル対応後の方を開いていただくとわかると思いますが、ページを開くのがとっても速くなってます!
また、一番見たいテストコード部分がすぐに確認できるようにもなりました。

Wandbox ますます便利になりましたね\(^o^)/

2015年4月20日月曜日

iutest_c v1.5.1 をリリースしました

iutest_c v1.5.1 をリリースしました。

bugfix バージョンです。
coveralls 連携がうまく動くようになったので、カバレッジ上げつつテスト書いてたらいっぱいバグが見つかりました(ノ∀`)
どうせならパワーアップして v1.6.0 を出そうかと思ったんですが、優先度的に"なし"になりました。

新しいことやりたいですしね( ^ω^ )

2015年4月14日火曜日

bat ファイルでアンインストールをする

Jenkins なんかでインストーラーの自動テストを組んでいると、
アンインストールをさせる必要も当然でてきます。

ただ、レジストリに登録されている名前が固定ならば良いのですが、
GUID の場合があるので汎用的に使えるようにバッチファイルを書きました。
(bat で結構いろいろできるんです)

レジストリを探す
インストーラーのアンインストール情報を探します。
情報は以下のノードに入ってます。
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKLM\SOFTWARE\Microsoft\Wow6432Node\Windows\CurrentVersion\Uninstall

regedit で上記ノードを見るとわかると思いますが、GUID やツール名などでキーがあります。
それを開くと DisplayName という名前の REG_SZ があります。ここに名前が格納されているので、これを鍵に情報を抜き出します。

まずは、DisplayName を参照しましょう。
レジストリの操作には reg コマンドを使用します。

if "%PROCESSOR_ARCHITECTURE%" == "x86" (
    SET REG_UNINSTALL_KEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
) else (
    SET REG_UNINSTALL_KEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
)
for /f "tokens=1,2*" %%A in ('reg query "%REG_UNINSTALL_KEY%"') do (
    reg query "%%A" /v DisplayName 2>NUL
    if not errorlevel 1 (
        pause
    )
)

上記 bat を実行すると Uninstall キーにあるキーの DisplayName の値をダンプしていきます。

>reg_uninstall.bat

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\552277EA-F57E-7211-F7F4-B8BA1274B46C
DisplayName REG_SZ GNU Tools for ARM Embedded Processors 4.8 2014q2

続行するには何かキーを押してください . . .



HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\AmUStor
DisplayName REG_SZ Alcor Micro USB Card Reader

続行するには何かキーを押してください . . .

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Arduino
DisplayName REG_SZ Arduino

続行するには何かキーを押してください . . .

こちらは、「キー名[改行] DisplayName REG_SZ 名前」のように出力されるので、この名前のところに目的のソフト名が含まれているかを調べます。


先ほどの bat ファイルを以下のように修正します。(一部省略)
例として AutoIt を探してますが、実際に使う際はこちらを目的のソフト名にしてください。
for /f "tokens=1,2*" %%A in ('reg query "%REG_UNINSTALL_KEY%"') do (
    reg query "%%A" /v DisplayName 2>NUL | findstr /c:"AutoIt" 2>NUL
    if not errorlevel 1 (
        goto :EOF
    )
)

実行するとこんな感じ。
>reg_uninstall.bat
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3
DisplayName REG_SZ AutoIt v3.3.8.1

これで、アンインストール情報が含まれたレジストリを見つけることができました。

アンインストールコマンドを得る
情報の格納キーがどこかわかったので、次に具体的なアンインストール方法を取得します。
アンインストール方法は UninstallString にあります。

先ほどのバッチを以下のように変え、実行します。
for /f "tokens=1,2*" %%A in ('reg query "%REG_UNINSTALL_KEY%"') do (
    reg query "%%A" /v DisplayName 2>NUL | findstr /c:"AutoIt" 2>NUL >NUL
    if not errorlevel 1 (
        reg query "%%A" /v UninstallString
        goto :EOF
    )
)

>reg_uninstall.bat
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\AutoItv3
UninstallString REG_SZ C:\Program Files (x86)\AutoIt3\Uninstall.exe

このように、アンインストール情報が得られるのでいらない部分を削除して使います。

for /f "tokens=1,2*" %%A in ('reg query "%REG_UNINSTALL_KEY%"') do (
    reg query "%%A" /v DisplayName 2>NUL | findstr /c:"AutoIt" 2>NUL >NUL
    if not errorlevel 1 (
        for /f "tokens=1,2*" %%B in ('reg query "%%A" /v UninstallString') do (
            if not "x%%D" == "x" (
                @echo "%%D"
            )
        )
        goto :EOF
    )
)

reg query を入力に for ループをしています。改行ごとにループが回るので、このループは2回まわるのに注意してください。
上記、バッチを実行すると以下のようにアンインストールコマンドが取得できます。

>reg_uninstall.bat
"C:\Program Files (x86)\AutoIt3\Uninstall.exe"

後は、コマンドを実行するだけです。

サイレントアンインストール
さて、ここまでできたらサイレントモードでアンインストールしたいですよね。
サイレントアンインストールは UninstallString ではなく QuietUninstallString にコマンドが格納されています。
QuietUninstallString はインストーラーによって、存在したりしなかったりするの注意してください。

存在しない場合でも、サイレントモードに対応していればコマンドライン引数で指定することでできると思います。



2015年4月6日月曜日

net use でシステムエラー 1219

net use z: \\hogehoge\jenkins のようにネットワークドライブを割り当てて Jenkins のジョブから参照してたりするんですが、これがたまに以下のようなエラーで失敗することがありました。

システム エラー 1219 が発生しました。

同じユーザーによる、サーバーまたは共有リソースへの複数のユーザー名での複数の接続は許可されません。サーバーまたは共有リソースへの以前の接続をすべて切断してから、再試行してください。

いつもは一度ログオフして再接続してましたが、コマンドだけで解決できたので備忘録として残しておきます。

状況
誰かが接続した状態になっているため接続できないようですが、net use コマンドで接続を確認してもそれらしいものは出ず… 試しにエクスプローラーでネットワークにアクセスしたら認証なしにフォルダが開けたので、どうやらログイン状態であるのは確かなようでした。

ググってみたところ、以下の記事が見つかりました。

みんな忘れてしまうんだ: [windows]ファイル共有を別ユーザーでログインする方法。(ネットワークフォルダの切断について)

こちらに書いてありますが、Windows 2000 以降ではエクスプローラーで接続したネットワークフォルダは net コマンドでは切断できないようです。

解決方法
上記のブログでは hosts ファイル編集して複数接続可能にしていましたが、もっと簡単に解決できます。

解決方法:
net use \\hogehoge\jenkins
net use \\hogehoge\jenkins /delete

net use /delete が net コマンドで接続したものしか切断できないのであれば、
net use で該当のネットワークに接続してから、切断すれば良いのです。

この方法がすべての環境でうまくいくかはわかりませんが、筆者環境ではうまくいきました。

今回は以上です。