2016年2月16日火曜日

呼出先WinアプリでSQLite の「unable to open database file」が出たら

自分用メモ。

普通はSQLiteのDBファイル、およびDBファイルがあるディレクトリに書き込み権限がない場合がほとんどだと思いますが、以下のような特殊な状況の場合の対応策。

シチュエーション

DBにSQLiteを使っているWindowsアプリケーション(例:SomeApp.exe)があって、それを別のWindowsアプリ(例:MyApp.exe)から引数2つを付けて呼び出さないといけない。
DBファイル(例:SomeApp.db)は、呼出先のEXEと同じ階層にある。

現象

MyApp.exeのコード(C#)から、SomeApp.exeをこんな感じで起動させようとする。引数は、「user001」と「C:\\work」の2つ。
[C#]
System.Diagnostics.Process p =
 System.Diagnostics.Process.Start(
  "C:\\SomeApp\\SomeApps.exe",
  "user001 C:\\work");
そうすると、件のエラー「unable to open database file」が出てしまう。

原因

SomeApp.exeが、「カレントディレクトリにあるDBファイル(SomeApp.db)を開く」という処理をしているため、別アプリから起動すると、別アプリ自体があるディレクトリをカレントディレクトリとして認識してしまうため、当然「カレントにDBファイルはないよ」となっている。まぁ、単純な話。

対応

以下の2つの手順を踏んで、無理やりSomeApp.exeがある場所がカレントになるようにSomeApp.exeを実行してあげる。

(1)SomeApp.exeの場所に移動してSomeApp.exeを起動するbatファイルを作る。
(2)呼出元のMyApp.exeからは、上記1のbatファイルをキックする。

まず、(1)のbatファイルはこんな感じ。
[kick.bat]
SomeApp.exeがあるフォルダに移動
cd "C:\\SomeApp" batファイル起動時の引数2つをそのまま渡す
SomeApp.exe %1 %2

次に、(2)の呼出方をこう変える。
[C#]
System.Diagnostics.Process p =
 System.Diagnostics.Process.Start(
  "C:\\Path\\to\\kick.bat",
  "user001 C:\\work");
以上、こんな状況、他にあるのか知らないけど備忘録として。