タグ: .NET

System.Data.SQLiteで共有フォルダのファイルを開くとunable to open database file

例えば以下のC#コードだとOpenで例外が投げられる。

var con = new SQLiteConnection();
con.ConnectionString = @"Data Source=\\FileServer\Test.db3;Version=3;";
con.Open();

ネットワークドライブだと大丈夫。で、よくわからないがUNCの最初の”\\”を”\\\\”にすると開けるようになる。

var con = new SQLiteConnection();
con.ConnectionString = @"Data Source=\\\\FileServer\Test.db3;Version=3;";
con.Open();

なんでだろ。後でリファレンス読んでみるか。

.NET 3.5のアプリを.NET 2.0と.NET 4.0環境で動かすと落ちる

現象

.NET Framework 3.5向けに作ったプログラムを、.NET Framework 2.0と.NET Framework 4.0がインストールされたWindows Vista環境で動作させると途中で落ちる。

エラーの詳細は以下のようなもの。

説明:
  Stopped working

問題の署名:
  問題イベント名:	CLR20r3
  問題の署名 01:	test.exe
  問題の署名 02:	1.0.0.0
  問題の署名 03:	52e6fd4a
  問題の署名 04:	test
  問題の署名 05:	1.0.0.0
  問題の署名 06:	52e6fd4a
  問題の署名 07:	23c
  問題の署名 08:	33
  問題の署名 09:	System.TypeInitialization
  OS バージョン:	6.0.6002.2.2.0.256.6
  ロケール ID:	1041

プライバシーに関する声明をお読みください:
  http://go.microsoft.com/fwlink/?linkid=50163&clcid=0x0411

app.configには以下の記載。

    <startup useLegacyV2RuntimeActivationPolicy="true">
      <supportedRuntime version="v2.0.50727" sku="Client" />
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
    </startup>

原因

上記のapp.configに従い.NET Framework 2.0で動作するものの、.NET Framework 3.5から用意されたライブラリは存在しないため。

.NET Framework 2.0で動作できるならば動作するので途中までは動くが、.NET Framework 3.5が必要なメソッド等(今回はLINQだった)を呼ぶと、アセンブリが無いので落ちる。

対応

app.configのsupportedRuntimeの記載順序を変えて、.NET Framework 4.0で優先的に動かせば大丈夫。

    <startup useLegacyV2RuntimeActivationPolicy="true">
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client"/>
      <supportedRuntime version="v2.0.50727" sku="Client" />
    </startup>

.NETでフォームを最前面表示かつ他ウィンドウのフォーカスを奪わないで表示

Outlookみたいな通知画面を出したかった

Outlookあるじゃないですか、あれって新着メールが来たら画面の右下にぴよっとポップアップというか、じわーっと表示される画面を出せますよね。あんなのを出したかった。
最前面に表示される、だがしかし、表示させるときには他のウィンドウのフォーカスを奪わない。Wordで文書を書いているときにフォーカス奪われたらたまったもんじゃない。

TopMost + ShowWithoutActivationじゃダメ

FormにはTopMostというプロパティがあり、こいつをtrueにすれば最前面表示される。また、ShowWithoutActivationというプロパティをオーバーライドしてtrueを返すようにすると、表示する際にアクティブにならない(他ウィンドウのフォーカスを奪わない)ので、これを組み合せれば良いはず。

ところが、TopMostをtrueにすると必ずアクティブになるようで、使えない。

SetWindowPosする

上記問題はTopMostプロパティを使わずに、SetWindowPosを呼べば解決できます。例えば、C#なら以下のメソッドを呼べばOK。

       private void SetTopMost()
       {
           const int HWND_TOPMOST = -1;
           const uint SWP_NOSIZE = 0x0001;
           const uint SWP_NOMOVE = 0x0002;
           const uint SWP_NOACTIVATE = 0x0010;
           const uint SWP_SHOWWINDOW = 0x0040;
           const uint SWP_NOSENDCHANGING = 0x0400;
            // SetWindowPosはどこかでDllImportする
           SetWindowPos(this.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_SHOWWINDOW);
       }

で、ShowWithoutActivation?をオーバーライドしtrueを返せば、所望の表示が可能。

参考サイト

参考というより、パクリ元と書くべきだな。