msys2、emacs(x64) 再インストール

msys2インストール

MSYS2 Wikiにて、msys2-x86_64-20150512.exe を取得し、インストールを実行します。

更新
  1. シェル(C:/MSYS64/mingw64_shell.bat)を起動します。
  2. pacman -Sy
  3. pacman --needed -S bash pacman pacman-mirrors msys2-runtime
    • いきなりpacman -Suすると、子プロセスのfork()に失敗するので、核となるパッケージを先に更新します。MSYS2のDLLはfork()の実装のために、全プログラムで同一アドレス空間を共有しているからです(と書いてあるような...)。
  4. 一旦シェルを終了し、再度シェルを起動します。
    • 前段の更新したパッケージが使用中となるので、一旦シェルを終了させる必要があります(と書いてあるような...)。
  5. pacman -Su
    • 残りの全パッケージの更新を行います。

あとは、お好きなパッケージをpacmanで取得、インストールします。

bash here

レジストリに直接設定します。昔作ったものが元になっているので、紆余曲折したままごまかしながら使ってます。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\shell]
@="mintty here [selected](&B)"

[HKEY_CLASSES_ROOT\Directory\shell\shell\command]
@="C:\\msys64\\usr\\bin\\mintty.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty.exe; exec bash --login -i'"

[HKEY_CLASSES_ROOT\Directory\shell\shell_sudo]
@="mintty sudo [selected](&B)"

[HKEY_CLASSES_ROOT\Directory\shell\shell_sudo\command]
@="C:\\msys64\\usr\\bin\\mintty_SUDO.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty_SUDO.exe; exec bash --login -i'"

[HKEY_CLASSES_ROOT\Directory\Background\shell\shell]
@="mintty here(&B)"

[HKEY_CLASSES_ROOT\Directory\Background\shell\shell\command]
@="C:\\msys64\\usr\\bin\\mintty.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty.exe; exec bash --login -i'"

[HKEY_CLASSES_ROOT\Directory\Background\shell\shell_sudo]
@="mintty sudo(&B)"

[HKEY_CLASSES_ROOT\Directory\Background\shell\shell_sudo\command]
@="C:\\msys64\\usr\\bin\\mintty_SUDO.exe -i /msys2.ico /usr/bin/bash -lc 'cd \"%V\"; export CHERE_INVOKING=1; export MSYSTEM=MINGW64; export MSYSCON=mintty_SUDO.exe; exec bash --login -i'"


emacs再インストール

インストール

chuntaroさんのx64バイナリを使います。emacs-24.5-IME-patched.zip
をダウンロードして展開、そのまま使えます。今回は、C:\utilities\emacs -> C:\utilities\emacs-24.5-IME-patched とシンボリックリンクを張るような配置にしました。

関連付け

emacsの再インストールでいっつも引っかかるのが、拡張子の関連付け、規定のプログラム指定などがうまくいかなくなることです。毎度、引っかかります。

  • [スタート]->[規定のプログラム]
  • ファイル選択 [右クリ]->[プロパティ]->[プログラム:変更]
  • ファイル選択 [右クリ]->[プログラムから開く...]

などで、再インストールしたrunemacs.exeが登録できません。エクスプローラで新しいrunemacs.exeを選択しても、プログラムとして認識されなくなるのです。

解決策は、レジストリで次の項目を削除するです。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Applications\runemacs.exe]

[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell]

[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open]

[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command]
@="\"C:\\Program Files\\GNU\\Emacs23\\bin\\runemacs.exe\" \"%1\""


古い設定が残っていて、新しいrunemacs.exeが空振りしているようです。HKEY_CLASSES_ROOT\Applications\runemacs.exeのツリーを削除しました。あとは、通常の関連付けができるようになります。あっ、システムが壊れても責任取りませんから。

次のURLを参照して下さい。

electron on VS2013

Electronfirst Electron appをビルド、実行します。

  • electron-prebuilt@0.28.3
  • Visual Studio Community 2013
  • (node.js@0.12.3)

Add New Project ...

TypeScriptのNode.jsプロジェクト、「Blank Node.js Console Application」を指定します。

package.json を作成

(package.json自体はVSが生成してくれてるので、中身を書き換えます。)
(tutorialでは、main.jsですが、app.jsにしました(なっちゃいました、してしまいました)。)

{
  "name"    : "your-app",
  "version" : "0.1.0",
  "main"    : "app.js"
}

app.ts を作成

(app.ts自体はVSが生成してくれるので、中身を書き換えます。)

var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    if (process.platform != 'darwin') {
        app.quit();
    }
});

// This method will be called when Electron has done everything
// initialization and ready for creating browser windows.
app.on('ready', function () {
    // Create the browser window.
    mainWindow = new BrowserWindow({ width: 800, height: 600 });

    // and load the index.html of the app.
    mainWindow.loadUrl('file://' + __dirname + '/index.html');

    // Open the devtools.
    mainWindow.openDevTools();

    // Emitted when the window is closed.
    mainWindow.on('closed', function () {
        // Dereference the window object, usually you would store windows
        // in an array if your app supports multi windows, this is the time
        // when you should delete the corresponding element.
        mainWindow = null;
    });
});

index.html

(新規に作成保存しました。)

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
</head>
<body>
    <h1>Hello World!</h1>
    We are using io.js
    <script>document.write(process.version)</script>
    and Electron
    <script>document.write(process.versions['electron'])</script>.
</body>
</html>

フォルダ内のファイル一覧

ビルド

プロジェクトのプロパティで「Node.exe path」にelectron.exeのパスを設定します。

実行結果


補足

iojs.exe が動いている?node.jsと同梱されてるのとは版が違うし...electron-prebuiltは、でかいです。npmでインストールしたらダウンロードで10分程度掛かる大きさです。このサイズなら何が入っててもおかしくない。io.js/node.jsの相違が現れるまで追求しません。

node-ffi char**

node-ffiを使って、JavaScriptからC++ DLL内で作成したchar*にアクセスする方法です。

C++でバッファを確保して、JavaScriptで受け取ります。JavaScriptで利用するとか、別のC++関数に渡すとかできます。バッファの確保をJavaScript内で行うという方法も考えられますが、char**の扱いが必要な場面での書き方の練習です。

app.ts
var ref = require('ref');
var ffi = require('ffi');

var mylib = ffi.Library('sub', {
    'fnsub_create': ['size_t', ['char**']]
});

var dataPtrPtr =ref.alloc('char*');
var len = mylib.fnsub_create(dataPtrPtr);

var dataPtr = ref.deref(dataPtrPtr);
var buf = ref.reinterpret(dataPtr, len, 0);

console.log('len       =', len);
console.log('dataPtrPtr=', dataPtrPtr);
console.log('dataPtr   =', dataPtr);
console.log('buf       =', buf);
console.log('   (ascii)=', buf.toString('ascii'));
console.log('   (value)=', buf[0], buf[1], buf[2], buf[3], buf[4]);

ちなみに、'char**'や'char*'は、'pointer'と書いても問題ないようです。

'fnsub_create': ['size_t', ['pointer']]
var dataPtrPtr =ref.alloc('pointer');
sub.h
#ifdef SUB_EXPORTS
#define SUB_API __declspec(dllexport)
#else
#define SUB_API __declspec(dllimport)
#endif

extern "C"{
	SUB_API size_t fnsub_create(char** dataPtrPtr);
}
sub.cpp
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include "sub.h"

SUB_API size_t fnsub_create(char ** dataPtrPtr)
{
	setlocale(LC_ALL, "japanese");

	char* dataPtr =*dataPtrPtr =new char[5];

	dataPtr[0] ='a';
	dataPtr[1] ='b';
	dataPtr[2] ='c';
	dataPtr[3] ='d';
	dataPtr[4] ='\0';

	std::cout << "dataPtrPtr:" << std::hex << std::setfill('0') << std::setw(16) << dataPtrPtr << std::endl;
	std::cout << "dataPtr   :" << std::hex << std::setfill('0') << std::setw(16) << (ULONGLONG)dataPtr << std::endl;

	return 5;
}

実行結果

dataPtrPtr:0000000001F81D10
dataPtr   :000000000204e9e0
len       = 5
dataPtrPtr= <Buffer@0x0000000001F81D10 e0 e9 04 02 00 00 00 00>
dataPtr   = <Buffer@0x000000000204E9E0 61>
buf       = <Buffer@0x000000000204E9E0 61 62 63 64 00>
   (ascii)= abcd
   (value)= 97 98 99 100 0

1,2行目はC++内でアドレスを印字したもの。
4,5行目はJavaScript内でアドレスを確認してます。
6行目はアドレス('pointer'タイプ)をNode.jsのBufferとして解釈したもの。

    var buf = ref.reinterpret(dataPtr, len, 0);

JavaScriptでBuffer確保

JavaScript内でBufferを確保して、C++に引き渡すのはずっと簡単です。

var mylib = ffi.Library('sub', {
    'fnsub': ['size_t', ['char*']]
});

var buf =new Buffer(5);

var len = mylib.fnsub(buf);

C++側は次のような宣言です。dataPtrは普通のバッファとして使えます。

  SUB_API size_t fnsub(char * dataPtr);

node-ffi wchar_t

障害

「のでーっふぃ」とかカワイイ...「ノードエフエフアイ」つまり、Node.jsがらみのForeign function interfaceです。C++ DLLとjavascriptをつなぐモジュールです。が、wchar_tがC++にうまく渡りません。困りました。

経緯

関連スペックは次のようになります。

テスト用のC++DLL関数は、次のように、引数がwchar_tです。

 size_t fnsub(const wchar_t* txt);


また、typesriptからは、次のように接続、呼び出しをします。

var ref = require('ref');
var ffi = require('ffi');
var wchar_t = require('ref-wchar');

var mylib = ffi.Library('sub', {
    'fnsub': ['int', [wchar_t]],
});

var ret = mylib.fnsub('愛あればこそ。');


結果は、不正アクセスで異常終了です。困りました。

対策

ref-wcharをあきらめ、同一作者のテストコードwchar_t.jsを改変して使いました。
Nathan Rajlich@TooTallNate's wchar_t.js

改変したwchar_t.js

// original author: Nathan Rajlich@TooTallNate
var ref = require('ref');
var ffi = require('ffi'); // added by eggtoothcroc
var Iconv = require('iconv').Iconv;

// vars used by the "wchar_t" type
var wchar_size, getter, setter;

// On Windows they're UTF-16 (2-bytes), but on Unix platform they're UTF-32
// (4-bytes).
if ('win32' == process.platform) {
    wchar_size = 2;
    getter = new Iconv('UTF-16' + ref.endianness, 'UTF-8');
    setter = new Iconv('UTF-8', 'UTF-16' + ref.endianness);
   } else {
    wchar_size = 4;
    getter = new Iconv('UTF-32' + ref.endianness, 'UTF-8');
    setter = new Iconv('UTF-8', 'UTF-32' + ref.endianness);
}

// Create a "wchar_t *" type. We use the "CString" type as a base since it's pretty
// close to what we actually want. We just have to define custom "get" and "set"
// functions and then we can use this type in FFI functions.
var wchar_t = Object.create(ref.types.CString);

wchar_t.get = function get(buf, offset) {
    var _buf = buf.readPointer(offset);
    if (_buf.isNull()) {
        return null;
    }
    var stringBuf = _buf.reinterpretUntilZeros(wchar_size);
    return getter.convert(stringBuf).toString('utf8');
};

wchar_t.set = function set(buf, offset, val) {
    var _buf = val; // val is a Buffer? it better be \0 terminated...
    if ('string' == typeof val) {
        _buf = setter.convert(val + '\0');
    }
    return buf.writePointer(_buf, offset);
};

wchar_t.ffi_type = ffi.FFI_TYPES.pointer;  // added by eggtoothcroc
module.exports = wchar_t;        // added by eggtoothcroc


テスト用javascript (app.ts)

var ref = require('ref');
var ffi = require('ffi');
var wchar_t = require('./wchar_t');

var mylib = ffi.Library('sub', {
    'fnsub': ['int', [wchar_t]],
});

var ret = mylib.fnsub('00愛0');
console.log('  len=', ret);

テスト用C++DLLヘッダ (sub.h)

#ifdef SUB_EXPORTS
#define SUB_API __declspec(dllexport)
#else
#define SUB_API __declspec(dllimport)
#endif

extern "C"{
	SUB_API size_t fnsub(const wchar_t* txt);
}

テスト用C++DLLソース (sub.cpp)

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include "sub.h"

SUB_API size_t fnsub(const wchar_t* txt)
{
	setlocale(LC_ALL, "japanese");
	std::wcout << "txt=" << txt << std::endl;
	std::cout
		<< std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[0] <<" "
		<< std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[1] <<" "
		<< std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[2] <<" "
		<< std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[3] <<" "
		<< std::hex << std::setfill('0') << std::setw(4) << (unsigned)txt[4] <<" "
		<< std::endl;
	return wcslen(txt);
}

実行結果

txt=00愛0
0030 0030 611b 0030 0000
  len= 4

補足

文字コードについて
javascript内部(string) UTF-16
FFI変換 UTF-16 -> UTF-8
C++内部(wchar_t) UTF-16LE

javascript内部文字コードのendiannessがBig EndianかLittle Endianかは解りませんが、FFIを通すと、外部に対してUTF-8になるようです。で、wchar_tはUTF-16LEなので、変換(UTF-8 -> UTF-16LE)しなければならないようです。

改変部分抜粋

オリジナルのwchar_t.jsから必須部分を抜き出すと次のようなコードになります。

var ref = require('ref');
var ffi = require('ffi');
var Iconv = require('iconv').Iconv;

var setter = new Iconv('UTF-8', 'UTF-16LE');

var wchar_t = {
    size: 8,
    indirection: 1,
    ffi_type : ffi.FFI_TYPES.pointer,
    get: function get(buf, offset) { return 'foo'; },
    set: function set(buf, offset, val) {
        var _buf = val;
        if ('string' == typeof val) {
            _buf = setter.convert(val + '\0');
        }
        return buf.writePointer(_buf, offset);
    }
}

module.exports = wchar_t;


重要なのは、ffi_typeの付加です。次のようにも書けます。

  wchar_t.ffi_type =ffi.FFI_TYPES.pointer;


このコードはあくまでも見通しを良くする為のもので、getは機能しません。エンディアンネスも考慮していません。このコードも含め、今回のコード改変は、FFIの機構を理解しないままで、正当性は二の次にして、動くということを試したものです。悪しからず。

vs2013 express + JavaScript

症状

VisualStudio 2013 Express for WEB 上で JavaScriptデバッグしたかったのですが、ブレークポイントが利きません・・・困った。

(追記じゃ)
  • NTVS Dev 2015-03-03 VS 2013.msi

なるものの存在を見つけました。普通にブレークポイントが利くそうですが、

  • NTVS 1.0 VS 2013.msi (Wed Mar 25, 2015 at 7:00 AM)

よりも古いので、インストールで断られました。開発版なので1.0よりも内容的には進んでいる可能性もありますが、次の正式版まで待つことにします(他の人達は問題なく動いているらしい。もしかして私だけとか...)。

(更に追記です)

VisualStudio2013 community版を使うことにしました。しかも、TypeScriptです。InntelliSenseもブレークポイントも利きます。苦労なし。

対策

ステップ・イン(F11)を使う。

経緯

JavaScriptPHPの変わりに使おうと目論んだのが動機でしたが見事に躓きました。昔は、emacsPerlを書き、その後はemacsPHPを書き。日々の作業をbashと共にこなすのが私の人生・・・なんと寂しい人生ではないか・・・そうじゃなくて・・・PCをアップデートしたのを機に、日常に変化を求め、PHPからJavaScriptに変更できないかと思ってしまったのです。
アプリを作るというのではなく、作業の自動化が目的です。.batや.shだと、DOMの扱いが面倒なのでPHPを使用しているのですが、JavaScript+Node.jsなら代替が利きそうだと思った訳です。
さて、次のような要望をemacs上で満たそうとすると、

  1. 補完したい。
    • js2-mode, tern-mode とか?
  2. デバッガ使いたい。
    • node.exe debug モードとか?

Node.jsも良くわからないのに環境整備とか鶏・卵です。早々に代替案を模索した結果、寄らば大樹のMicrosoftさんにお世話になろうと思いました(だめなら、emacsに戻ればいいのですから)。

インストール

VisualStudio Express 2013 for web とNode.jsをインストール。

  • vns_full.exe
  • NTVS 1.0 VS 2013.msi
  • node-v0.12.3-x64.msi
新規プロジェクト作成 [ファイル][新しいプロジェクト...]

おぉ、JavaScript, Node.js が使えます。とりあえず、Console で。

[OK]

ほほぅ、できましたね。Hello アプリです。

補完

ひゃはっ、インテリセンスさまさまです。

実行、ブレークポイントが利きません

何じゃこりゃ?「ブレークポイントは現在の設定ではヒットしません。」

No code has been loaded for this code location.

ステップ・イン

色々、ぐだぐだして、検索しても結局わからずじまい。なんだか、「アタッチプロセス」しろというのであすが、Expressにはそんなものありません。製品版を買えと?んな高いもの?・・・インテリセンスでよしとして、デバッガはnode.exeのデバッグモードでもいいかぁ・・・と思ったのでした・・・が、たまたま、ステップ・インしたらできました。

続行

ほらほら、続行したら、ブレークポイントで止まってる。ローカル変数の表示もされてる(実行窓の後ろで見えにくいけど)。

もちろん、続けて、続行したらちゃんと最後までいきます。

うーん、なんでapp.jsが2枚あるんだ?わかりませんが、とりあえずブレークできたので、よしとします。

蛇足

この2枚のapp.jsは、ブレーク・ポイントが利くのと、利かないのが1枚ずつあるという不気味さ。閉じても大丈夫なのか?間違ったほうを閉じたら、また、ブレークポイントが・・・と思いましたが、ステップ・イン使えば問題は無いようです。
全閉じしておいて、F11(ステップ・イン)すれば、ブレーク・ポイントが有効な1枚だけが開きます。不気味だ。
(以上)

ファイルの関連付け沈黙

症状

.texがrunemacsに関連付けられない。

環境は、win7 64bit+msys64+NTEmacs

原因

GNUPACK emacsにファイルの関連付けをしたまま、アンインストールし、NTEmacs64をインストールしたところ、古い関連付けが不正になったため、新しい関連付けを受け付けなくなったらしいです。

GNUPack emacs gnupack_basic-12.00-2014.12.29.exe
NTEmacs64 emacs-24.5-IME-patched-generic-cpu.zip

対策

レジストリを書き換えます。

[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command]
@="\"C:\\emacs-24.2-20121208\\bin\\runemacs.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Applications\runemacs.exe\shell\open\command]
@="\"C:\\msys64\\usr\\bin\\runemacs.exe\" \"%1\""


あとは、通常通りの方法でファイルの関連付けを行います。[右クリ][プロパティ][全般][プログラム][変更]

ASRock A-Tuning FAN-Tastic でレベル(T1)が動かない

症状

ASRock A-Tuning Utility / FAN-Tastic Tuning レベル設定用のグラフで玉が動かなくなってしまった。わかり辛いので下の図で説明すると、「T1の玉」が「T0の玉」とくっついてしまって、動かなくなってしまうという症状です。

「T0の玉」は説明の為に命名したものです。本来、T0はT1と分離して(下に正常時のスクショ貼りました)、Temparature=0に張り付いていて、T1のFAN Speedに追従するはずなのですが、T1をうっかりT0とくっつけてしまうと、一体化して動かなくなってしまうのです。

対策

A-Tuningの設定ファイル(.xml)をメモ帳などで直接書き換える。

C:\Program Files (x86)\ASRock Utility\A-Tuning\Conf\Z97E4.xml

編集前

Z97E4.xmlの次の箇所「T1=0」になっているとT0とくっついて動かないので、適当に書き換えます。例えば「T1=20」などに書き換えます。
「T1=0」→「T1=20」

<GUIFanControl Enable="1" AutoApply="1">
  <Item Name="FAN5" Enable="1" Interface="SIO_FAN" SmartFan="4" Control="FanReading"
    T1="0" T2="30" T3="46" T4="61" TCritical="80"
    SPD1="0" SPD2="0" SPD3="50" SPD4="100" ApplyValue="" ModelName="P67E4"
    LANID="STR_FANTUNING_CHASSIS_FAN2">
  CHASSIS FAN2
  </Item>
</GUIFanControl>

編集後

「T1=20」になった状態です。

<GUIFanControl Enable="1" AutoApply="1">
  <Item Name="FAN5" Enable="1" Interface="SIO_FAN" SmartFan="4" Control="FanReading"
        T1="20" T2="30" T3="46" T4="61" TCritical="80"
        SPD1="0" SPD2="0" SPD3="50" SPD4="100" ApplyValue="" ModelName="P67E4"
        LANID="STR_FANTUNING_CHASSIS_FAN2">
    CHASSIS FAN2
  </Item>
</GUIFanControl>


これを保存します。あらかじめA-Tuningは閉じておかないと上書き禁止になります。上書きできない場合は、別フォルダに保存しておいてコピーするなどして下さいね。

確認

A-Tuningを立ち上げてみると、T0とT1が離れていることが確認できます。

(以上です)