64bit版Windowsでの「Microsoft.Jet.OLEDB.4.0」について

# はじめに
新しいPCを購入すると64bit版Windowsになっていることが多くなってきました。.NET(AnyCPU)のアプリケーションなどで「Microsoft.Jet.OLEDB.4.0」を使用してMDBやExcelの操作をしようとした場合、下記エラーが発生します。
「'Microsoft.Jet.OLEDB.4.0' プロバイダはローカルのコンピュータに登録されていません。」
原因は、64bit版Windowsには「Microsoft.Jet.OLEDB.4.0」が提供されていないためです。
では、どうするかというと64bit版Windowsには32bitプログラムを動かす仕組み「WOW64」がありますので、その環境内でなら「Microsoft.Jet.OLEDB.4.0」が使用することができます。

# 対応方法
  * BATファイルの場合、32bit環境の「%windir%\SysWOW64\cmd.exe」を使用する。
  * VBScriptファイルの場合、32bit環境の「%windir%\SysWOW64\cscript」を使用する。
  * プロバイダを「Microsoft.ACE.OLEDB.12.0」に変更する。
  * .NETの場合、AnyCPUではなくx86でコンパイルする。

https://qiita.com/yaju/items/7b0aa9e9f30005f60388

# プロバイダの変更
VBSなどにプロバイダの記述がある場合は下記のように書き換える。
"Provider=Microsoft.Jet.OLEDB.4.0;" → "Provider=Microsoft.ACE.OLEDB.12.0;"

但し、これにはAccess2010以降がインストールされているか、Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントのインストールが必要。
※Microsoft.ACE.OLEDB.12.0は、32bit版と64bit版の両方が提供されます。
参照:[Microsoft Access データベース エンジン 2010 再頒布可能コンポーネントのダウンロード](https://www.microsoft.com/ja-JP/download/details.aspx?id=13255)

64bit版Windowsに32bitOffice環境がインストールされている場合、すでにOffice32bitが入っているためインストーラーのチェックにひっかかり、インストールが中止されてしまいます。
（Officeは32bitと64bitのサイドバイサイドインストールはできません。）
~~その場合、下記サイトを参考に強制的にインストールします。
参照:[32bitOffice環境で64bitMicrosoft.ACE.OLEDB.12.0プロバイダを導入する方法](http://plus-sys.jugem.jp/?eid=446])
ただ、強制的にインストールするとExcelなどのOfficeアプリケーションを開く度に、Windowsインストーラーが起動し構成の進行状況の画面が起動するようになってしまいます。(終わるまで待たなくても、途中で閉じてもExcelは使えます。)
また、Accessに関しては起動できない旨のエラーと再インストールしてくださいのメッセージが表示されてしまいます。~~

【追記 2017/10/20】
「Microsoft Access データベース エンジン 2016 再頒布可能コンポーネント」が出てますね。日本での情報は何も無いですけど。
[Microsoft Access Database Engine 2016 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=54920)

>If Office 365 is already installed, side by side detection will prevent the installation from proceeding. Instead perform a /quiet install of these components from command line. To do so, download the desired AccessDatabaseEngine.exe or AccessDatabaeEngine_x64.exe to your PC, open an administrative command prompt, and provide the installation path and switch Ex: C:\Files\AccessDatabaseEngine.exe /quiet

追加情報(Additional Infomation)には64bit版Windowsに32bitOffice環境がインストールされている場合、コマンドプロンプト上にて quietモードでインストールを実行すると書かれています。
AccessDatabaseEngine_x64.exe /quiet

## プロバイダとAccesssバージョン
  * Microsoft.ACE.OLEDB.12.0(Access2007,Access2010)
  * Microsoft.ACE.OLEDB.15.0(Access2013)
  * Microsoft.ACE.OLEDB.16.0(Access2016)

※Access2013は Microsoft.ACE.OLEDB.12.0 として呼び出すと例外吐くようなので、15.0として呼び出すか、上のコンポーネントを入れます。2016は12.0 or 16.0どちらでも。
参照：[ADO.NETでExcelファイルに接続する](http://qiita.com/unarist/items/6cc35bb9fe502ced332f)

# .NETのx86への変更
ソースリストがあればx86でコンパイルし直せばいいが、実行ファイルしか存在しない場合は下記ツールを使用する。
.NETアプリのAnyCPUを32bitに変換するツール
「[CorFlags 変換ツールCorFlags.exe](https://msdn.microsoft.com/ja-jp/library/ms164699(VS.80).aspx)」

参照:[アセンブリーの対応CPU(X86, X64)を確認](https://moated.wordpress.com/2011/05/11/windows-%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%AA%E3%83%BC%E3%81%AE%E5%AF%BE%E5%BF%9Ccpux86-x64%E3%82%92%E7%A2%BA%E8%AA%8D/)

## 使用方法
```bat
corflags [.NETの実行ファイル(exe)のパス] /32BIT+
```
## 確認方法
```bat
corflags [.NETの実行ファイル(exe)のパス]
PE : PE32
CorFlags : 1
ILONLY : 1
32BITREQ  : 1
32BITPREF : 0
Signed    : 0
```
※32BITREQに「1」が立つのを確認する。ファイルの更新日時は変更されません。

```
【VS2012 以上に付属の CorFlags の場合】
PE = PE32+ および 32BITREQ = 0 および 32BITPREF = 0　→　x64 ビルド
PE = PE32 および 32BITREQ = 1 および 32BITPREF = 0　→　x86 ビルド
PE = PE32 および 32BITREQ = 0 および 32BITPREF = 1　→　Any CPU (32 ビットの優先: On) ビルド
PE = PE32 および 32BITREQ = 0 および 32BITPREF = 0　→　Any CPU (32 ビットの優先: Off) ビルド

【VS2010 以下に付属の CorFlags の場合】
PE = PE32+ および 32BIT = 0　→　x64 ビルド
PE = PE32 および 32BIT = 1　→　x86 ビルド
PE = PE32 および 32BIT = 0　→　Any CPU ビルド
```

顧客管理システム「ワイドベース」は、この方法で使用できるようになりました。
[ワイドベースと言うDBをWin１０で使いたい](https://qiita.com/nanjyamondayo/items/6b6444973075df74e27b)

# .NETのAnyCPUの場合
AnyCPUのままの場合、64bitではドライバーを切り替えないとエラーになります。IntPtr.Size == 8だと64bitであると判定できるため、ドライバーを切り替えます。
Accessがインストールされていない環境では「Microsoft.ACE.OLEDB.12.0」はMicrosoft Access データベース エンジン 2010 再頒布可能コンポーネントのインストールしないと使えないこともあって、この方法はお勧めしません。  
x86でコンパイルしておくのが無難な気がします。

```csharp

//MDB用のDBドライバー文字列
public const string MDB_ACCESS = "Microsoft.ACE.OLEDB.12.0";

    //接続文字列
    _connectionstring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=";
    if (IntPtr.Size == 8) {
        //64bitでは「Microsoft.Jet.OLEDB.4.0」は使えない
        _connectionstring = "Provider=" + ConstData.MDB_ACCESS + ";Data Source=";
    }

    _connectionstring += SystemInfo.MDBFileName + ";Persist Security Info=False";
```
# 最後に
もはや、新規開発で軽量データベースなら「SQLite」でいいと思います。Accessはレポート機能があるのがメリットくらい。
既存アプリケーションの改善作業で仕方なくmdbを使う必要がまだあったりするんですよね。