ホームページ「sorceryforce.net」の実行環境を変更しました

内部フレームワークを変えただけなので見た目とかは特に何も変わっていません。

開発環境を Windows 10 や Visual Studio 2015 に移行したりしていたのですが、ついでなのでホームページを動かしている ASP.NET の中身もいろいろバージョンを上げてみました。もし挙動などがおかしければコメントいただけると助かります。(WordPress 側は特に変えてないのでブログのほうは大丈夫だと思います)

一応変えてみたものは次の通りです。

  • ASP.NET 4 → ASP.NET 4.5.2
  • .NET Framework 4 → .NET Framework 4.5.2 (サーバーがいつの間にか 4.5 対応していたので上げました)
  • Entity Framework 5 → Entity Framework 6.1.2 (4→5 みたいに API 変わってなくてよかったです)
  • jQuery 1.8.2 → jQuery 1.10.2

ただ、Web サーバーのほうが権限の問題で Roslyn を使おうとするとアクセス権エラーが発生してホームページがまったく動かなかったので、web.config から「system.codedom」を抹消して使用しないようにしました。というか自作サーバーでテストしていたときは普通に動いていたのに、いざ本番ホームページサーバーにあげたら不明なエラーが発生して動かなかったので結構焦りました。一時期ホームページが開けなくなっていたのはこのためです。

ちなみに、作り直す前のプロジェクトを VS2013 から VS2015 に移行した時に図のような警告が出ていたので、SQL Server 2012 Express LocalDB を入れようかと思ったのですが、新規に作り直した時に認証系などをすべて外したので警告は出なくなりました。

2015-09-09 20_17_36-Microsoft Visual Studio

]]>

ASP.NET アプリケーションをデバッグ実行したときに「AspAccessCheck~.tmp」へのアクセス拒否のエラーに対処する

メモ書きです。

環境

  • Visual Studio 2013
  • .NET Framework 4.5

内容

原因がよくわかっていないのですが、Visual Studio で ASP.NET アプリケーションをデバッグ実行したときに以下のエラー(例外)が表示されて、その後の処理が正常に行われない現象が発生する場合があります。

型 'System.UnauthorizedAccessException' の初回例外が mscorlib.dll で発生しました

追加情報:パス 'C:WindowsMicrosoft.NETFrameworkv4.0.30319Temporary ASP.NET Files~AspAccessCheck_71d98a9c21352.tmp' へのアクセスが拒否されました。

※「71d98a9c21352」はたぶん一時的に決められた値

これを解決するには「C:WindowsMicrosoft.NETFrameworkv4.0.30319」フォルダにある「Temporary ASP.NET Files」フォルダを削除してしまいます。たぶんフォルダの中には何も入っていないはずです。削除後デバッグ実行すると正常に動作する場合があります。(実行しても Temporary ASP.NET Files フォルダは作成されないようです)

]]>

Entity Framework にて文字列の部分一致検索を行う

メモ書きです。

using (var entities = new xxxxxxEntities())
{
  var persons = from item in entities.Person
                where item.Name.Contains(keyword)
                select item;
}
// xxxxxxEntities は .edmx ファイルから生成されたエンティティクラス
// entities.Person はデータベースのテーブルから取得、生成されたクラス・プロパティ
// keyword は検索文字列

]]>

[.NET] 他のコントロールに押下キーの情報を渡す

アクティブでないウィンドウやコントロールに対してキーボードのキーを押したかのように情報を送るには、対象コントロールなどにフォーカスを当てて「SendKeys.Send」メソッド(または SendKeys.SendWait メソッド)を使うことによって送ることができます。

例えば、以下の例ではフォームがアクティブになっている状態でキーを押したときにテキストボックスに押したキー情報を送ってテキストを入力することができます。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  SendKeys.SendWait(e.KeyChar.ToString());
}

フォームでキーが押されたときに Focus メソッドでテキストボックスにフォーカスを当て、SendKeys で押されたキーを送っています。送ったあとフォーカスを戻すのがベストだとは思いますが、必要に応じて入れてください。

基本的なコードはこれで OK なのですが、SendKeys では一部のコードが特殊な用途に使用されるキーであるため、このままでは送ることができません。対象キー、用途については以下の MSDN の SendKeys を参照してください。

特殊キーを通常の入力キーとして送るには中括弧({})で囲む必要があります。これを踏まえるとコードは以下のようになります。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}

これで一見完成のように見えるのですが、実は動かしてみると「^(カレット)」キーを押したときになぜか「&(アンパサンド)」で送られてしまいます。.NET Framework のバグかはわかりませんが、これでは完全とは言えないため別案を使います。

WSH (Windows Script Host) にも同様に SendKeys の仕組みがあり、こちらは正常にカレットが送るのでこれを使います。WSH を使うには以下の手順を行う必要がります。

  1. 参照設定の追加で、COM タブから「Windows Script Host Object Model」を追加する。
  2. 参照設定に追加された「IWshRuntimeLibrary」のプロパティを開き、「相互運用機能型の埋め込み」を False に設定する。

そのうえで以下のようにコードを修正します。#if の条件を入れていますが、WSH を使うか使わないかで分けているだけなので不要であれば消してください。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
#if true // Interop.IWshRuntimeLibrary を使ってよい場合
      (new IWshRuntimeLibrary.WshShellClass()).SendKeys("{^}");
      break;
#endif
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}
]]>

OLEDB を使用して Excel ファイル(2007 形式)を読み込む際の接続文字列

メモです。必要そうな項目のみ列挙しています。

接続文字列の例

Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:Test.xlsx; Extended Properties="Excel 12.0; HDR=YES; IMEX=1;”

接続文字列パラメータ

Provider 使用する OLEDB のバージョン。2007 形式の Excel ファイル(.xlsx)を読み込みたい場合は「Microsoft.ACE.OLEDB.12.0」を指定。2003 以前の形式のみ(.xls)で構わないのであれば「Microsoft.Jet.OLEDB.4.0」も可。
Data Source 読み込む Excel ファイル名。またはファイルパス。
Extended Properties 拡張パラメータ。(以下参照)

 

Extended Properties パラメータ

Excel {バージョン} ISAMバージョン。2003 以前の形式の場合は「8.0」。2007 形式の場合は「12.0」
HDR シートの1行目をヘッダ列として扱う場合は「YES」、1行目から行データとして扱う場合は「NO」
IMEX 0:エクスポート モード、1:インポート モード、2:リンク モード。通常指定する必要がないが、1 を指定すると、セルの値がすべて表示されているテキストのまま読み込める。例えば、セルに「2011/10/1」と入力し、書式設定によって「2011年10月1日」と表示されている場合、IMEX に 1 を指定すると取得するデータは「2011年10月1日(string型)」となる。IMEX を指定していない場合はエンジンの自動解釈によって「2011/10/1(Date型)」として読み込まれるが、前後行の入力内容によって型の解釈が変化する。詳しくは「[PRB] DAO の OpenRecordset を使用すると Excel の値として NULL が返される」参照のこと。
]]>

Type クラス同士の比較結果 [.NET Framework]

サンプルコード

namespace TypeFullName
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t1 = typeof(TypeFullName.Test1.ClassSample);
            Type t2 = typeof(TypeFullName.Test1.ClassSample);
            TypeFullName.Test1.ClassSample samp1 = new Test1.ClassSample();
            TypeFullName.Test1.ClassSample samp2 = new Test1.ClassSample();
            Type t3 = samp1.GetType();
            Type t4 = samp2.GetType();
            System.Diagnostics.Trace.WriteLine("t1 == t2      : " + (t1 == t2));
            System.Diagnostics.Trace.WriteLine("t3 == t4      : " + (t3 == t4));
            System.Diagnostics.Trace.WriteLine("t3.Equals(t4) : " + t3.Equals(t4));
        }
    }
    namespace Test1
    {
        public class ClassSample
        {
            public int A;
        }
    }
}

結果

t1 == t2      : True
t3 == t4      : True
t3.Equals(t4) : True
]]>