Author Archives: admin

IEで表示が真っ白になる。

IEでなぜかページが真っ白になる問題。IE7のいわゆる真っ白問題とは別にIE6でも起こる問題です。

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

が<title>より後にあると真っ白になる場合があるので<title>より前、というより日本語が出現する前に置くと直る。

cygwinからキーペアを使ってsshで接続する

cygwinにopensshがインストールされていなければなりません。http://cygwin.com/からsetup.exeを実行し、opensshにチェックを入れインストールします。

Install openssh on ciygwin

コマンドラインから ssh-keygen を実行する。パスワードを入力し成功すると、~/.ssh/id_rsa に秘密カギが作成され、~/.ssh/id_rsa.pub に公開カギが作成される。

公開カギをサーバーにアップロードし、サーバーの ~/.ssh/authorized_keys に追加する。

例:
$ cat id_rsa.pub >> .ssh/authorized_keys

cygwinで ssh <server> -l <server-username> で接続する。

注:cygwinは日本語をうまく扱えないみたいなので日本語を扱いたい場合は poderosa などのクライアントをつかったほうがいいと思います。

vmware-vdiskmanager.exeでvmwareのディスクファイル .vmdkを2Gに分割する

vmwareのハードディスクファイル.vmdkは最初に作成するとき、ファイルを分割しないか2Gで分割するかを選択できます。FATファイルシステムでは4G以上のファイルは作成できないので2Gで分割することになりますが、すでに分割なしで作成されている.vmdkを2Gに分割する方法はGUIレベルでは提供されていません。

これを行うにはコマンドラインツール vmware-vdiskmanager.exeを使います。このファイルはvmwareがインストールされたフォルダに存在します。(Windowsを想定)

注:以下の作業は危険なのでバックアップを取ってから行ってください。

1、ゲストOSをシャットダウンする(してない場合)

2、vmwareを終了する。

2、コマンドプロンプトを開き、.vmdkファイルがあるフォルダへ移動する。

3、.vmdkを一時的にリネームする。(同名の分割ファイルを作成するため)。ここではaaa.vmdkとします。

"<path_to_vmware>\vmware-vdiskmanager.exe" -n original.vmdk aaa.vmdk

4、vmware-vdiskmanager.exeを使って2Gに分割する。

"<path_to_vmware>\vmware-vdiskmanager.exe" -r aaa.vmdk -t 1 original.vmdk

上記の -t 1は2Gで可変長のディスクに変換します。固定長にしたい場合は -t 3 を指定します。

5、vmwareを起動して異常がないか確認後、aaa.vmdkを削除します。

分割してない.vmdkをFATで使っていると4Gを越えた瞬間にエラーになります。エラーを起こしたファイルはそのままでは上記の方法を使えないのでいったんNTFSへゲストOSを移動し、そこでvmwareで開けば自動的にエラーを修復してくれます。その後2Gに分割してからFATへ戻します。

関連記事:
サーバとして利用しているvmwareゲストのハードディスクを圧縮する

Fedoraのvmware-serverでゲストOSのubuntuのホイールマウスが機能しない

/etc/X11/xorg.conf のInputDeviceセクションのConfigured MouseのところのProtocolをps/2からIMPS/2に変えると動いた。

参照: http://www.vmware.com/community/thread.jspa?messageID=504906

NBonline 「地域間格差拡大論のウソ」は本当?

Nikkei Business online「地域間格差拡大論のウソ」と言う記事が掲載されました。

この記事では、地域間経済格差が「イメージで語られている 」と言い、その理由を「損をしている人は騒ぎ、得をしている人は騒がない」と言っています。

自分は経済の専門家でもなんでもないのですが、どうも釈然としないので自分なりに調べてみました。まず記事にある内閣府作成の県民経済計算とはこのページのことだと思うので、このページの資料を眺めてみました。

まず概要1のPDFを読むと、いきなり「1人当たり県民所得の都道府県間ばらつきを変動係数でみると、3年連続拡大。」と書いてあります。これはまさに地域間経済格差が拡がっているということなのではないのでしょうか?

しかし日経の記事では”「ジニ係数」という概念で全体の格差度合いを計測するのが定石である。”として、 「格差が縮小している」としています。これは後で計算してみようと思います。

また記事では「年次経済財政報告(平成16年度)」でも同様の指摘がある、としています。それはこの資料)ことだと思いますが、ここの資料は2001年までのデータしか見ていません。もっと新しいのはないのかと思い調べてみたところ図だけ見つかりました。この図をみると2003年で全国平均との乖離がすべての地域で増えているのがわかります。この図に対応する年次経済財政報告書は見つかりませんでしたが、この図と照らし合わせれば、格差が縮小しているとは言えない、となるのではないでしょうか?

ここまで見る限りこの日経の記事はかなり意図的に感じました。「損をしている人は騒ぎ、得をしている人は騒がない」に習って言うなら、「損ををしている人は格差拡大を騒ぎ、得をしている人は格差縮小を騒ぐ」ということでしょうか?

いずれにしてもこの記事はもっと調査したいので、次回ジニ係数について調べてみようと思います。

UTF8 ini

Vistaになってiniファイルに対して勝手なことされるので、.netのcpp/cliでUTF8でiniを扱うクラスを作りました。Windows98系でも動くはずです。
iniファイルとの整合性は全然取れてませんけど。


// WProfile.h
#pragma onceusing namespace System;
using namespace System::Collections;
namespace WProfiler {public ref class WProfile
 {
 private:
  WProfile(){}
  ~WProfile(){}

static Hashtable^ readall(String^ inipath);
  static bool writeall(Hashtable^ al, String^ inipath);
 public:
  static System::Boolean WProfile::WGetPrivateProfileInt(String^ app, String^ key, int def, int% ret, String^ inipath);
  static System::Boolean WProfile::WWritePrivateProfileInt(String^ app, String^ key, int val, String^ inipath);
  static System::Boolean WProfile::WGetPrivateProfileString(String^ app, String^ key, String^ def, String^% ret, String^ inipath);
  static System::Boolean WProfile::WWritePrivateProfileString(String^ app, String^ key, String^ val, String^ inipath);
 };
}


// これは メイン DLL ファイルです。
#include "stdafx.h"#include
#include "WProfile.h"
using namespace System;
using namespace System::Collections;

namespace WProfiler {

Hashtable^ WProfile::readall(String^ inipath)
 {
  Hashtable^ al = gcnew Hashtable;
  try {
  System::IO::StreamReader sr(inipath, System::Text::Encoding::UTF8);

String^ line = nullptr;
  Hashtable^ cursec = nullptr;

while ( (line=sr.ReadLine()) != nullptr )
  {
  line = line->TrimStart();
  if ( line->Length==0 || line[0] == L'#' )
  continue;

if ( line[0] == L'[' )
  {
  String^ secname = line->Trim( gcnew array{'[', ']'} );
  cursec = (Hashtable^)al[secname];
  if ( cursec == nullptr )
  {
  cursec = gcnew Hashtable;
  al[secname] = cursec;
  }
  continue;
  }
  else
  {
  if ( cursec == nullptr )
  continue;

array^ vals = line->Split( gcnew array{L'='}, 2 );
  if ( vals->Length < 2 )
  cursec[vals[0]] = L"";
  else
  cursec[vals[0]] = vals[1];
  }
  }
  }
  catch ( System::Exception^ )
  {
  return nullptr;
  }
  return al;
 }

bool WProfile::writeall(Hashtable^ al, String^ inipath)
 {
  if(!al)
  return false;

try {
  System::IO::StreamWriter sw(inipath, false, System::Text::Encoding::UTF8);

for each(String^ secname in al->Keys)
  {
  sw.Write(L"[");
  sw.Write(secname);
  sw.Write(L"]");
  sw.WriteLine();

Hashtable^ sec = (Hashtable^)al[secname];
  if ( !sec )
  continue;

for each( String^ keyname in sec->Keys )
  {
  sw.Write(keyname);
  sw.Write(L"=");
  sw.Write(sec[keyname]);
  sw.WriteLine();
  }
  sw.WriteLine();
  }
  }
  catch(System::Exception^ )
  {
  return false;
  }
  return true;
 }

System::Boolean WProfile::WGetPrivateProfileInt(String^ app, String^ key, int def, int% ret, String^ inipath)
 {
  ret = def;
  Hashtable^ al = readall(inipath);
  if ( !al )
  return false;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  return false;

String^ val = (String^)sec[key];
  if ( !val )
  return false;

if ( !System::Int32::TryParse(val, ret) )
  return false;

return true;
 }

System::Boolean WProfile::WWritePrivateProfileInt(String^ app, String^ key, int val, String^ inipath)
 {
  Hashtable^ al = readall(inipath);
  if ( !al )
  al = gcnew Hashtable;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  {
  sec = gcnew Hashtable;
  al[app] = sec;
  }

sec[key] = val;

return writeall(al, inipath);
 }

System::Boolean WProfile::WGetPrivateProfileString(String^ app, String^ key, String^ def, String^% ret, String^ inipath)
 {
  ret = def;
  Hashtable^ al = readall(inipath);
  if ( !al )
  return false;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  return false;

String^ val = (String^)sec[key];
  if ( !val )
  return false;

ret = val;
  return true;
 }

System::Boolean WProfile::WWritePrivateProfileString(String^ app, String^ key, String^ val, String^ inipath)
 {
  Hashtable^ al = readall(inipath);
  if ( !al )
  al = gcnew Hashtable;

Hashtable^ sec = (Hashtable^)al[app];
  if ( !sec )
  {
  sec = gcnew Hashtable;
  al[app] = sec;
  }

sec[key] = val;

return writeall(al, inipath);
 }
}

ダウンロード

アプリケーションの設定をどうやって保存するか? ini vs レジストリ vs xml

1, その保存場所について

いままでは設定の保存はGetPrivatePrifile* APIを使ってiniファイルに保存していればよかったんですが、Vistaの登場でそういうわけにはいかなくなってしまいました。Vistaでは”Program files”下に置かれたアプリがexeのあるフォルダにファイルを作ることも書き込むことも許してくれないみたいです。

iniファイルの利点は、フォルダを削除すればアプリケーションのすべてのファイルを一括削除できることにあると思います。痕跡は残りません。もちろんOSがいろいろ残すでしょうから痕跡が全く残らないわけではありませんが。また設定ファイルのせいでアプリの挙動がおかしくなったときでも、iniファイルを削除してしまえば初期値に戻るので復旧が簡単です。

復旧といえばインストーラでインストールもアンインストールもできなくなって困った経験がある人も多いんじゃないでしょうか?

さて、レジストリに書き込むとユーザーごとに別々の場所に書くことになるので、アンインストーラーが本当に全員分の設定を削除してくれているのかはわかりません。もちろんこれはユーザーごとの”Documents and Settings”配下にデータを置いた場合も同じです。つまりアプリを色々使えば使うほどゴミファイルがどんどんたまっていってしまうのです。またアプリの設定場所が固定されているとウイルスも作りやすくなってしまいます。

よってアプリの設定情報は、そのフォルダの配下に置いた方がいいんじゃないでしょうか。ユーザーごとに分けたい場合は”user”フォルダを作成し、その配下におけばいいですし。

2, 保存のフォーマット

話は変わってxmlですが、なんか呼び方がserialilzeとかdeserializeとかになってますね。でもこれって退化じゃないでしょうか?いままではそういうことを意識しなくてもよかったのに連続化という下位概念を持ち出してくるわけですから。

そしてこれは言葉の問題だけじゃなくて本当に意識しなければいけないのではないでしょうか?iniファイルやレジストリの場合には、保存の際、それが壊れてしまうということを意識しなくてもよかったと思いますが、xmlで一気に書くとなると、もし書き始めたときにPCが固まってしまったら全部壊れるんじゃないかとか、また、ユーザーがエディタでそれをいじって読み込み不能になって、終了時デフォルト値のまま全部保存しちゃって結局全部消えちゃうとか、あるいはクラスの構成が変わったときの互換性は大丈夫かとか、考えなくてはいけないことが一気に多くなるような気がします。もちろんちゃんと調べたわけではないので嘘いってるかもしれませんが。

逆にxmlで有利な点はUTF-8で書けることだとおもいます。そしてそれはWindows98系でも同じなんでしょう(多分)。iniファイルだとそれが難しいです。W系のAPIを使ってしまうと98系で動かなくなりますし、A系だと中国語や韓国語が保存できません。あえてやるとすればGetPrivateProfileStructでバイナリ保存でしょうが、これだとユーザーが編集できなくなってしまいます。