Der beste Weg, dies zu tun ist über PInvoke Sie müssen den CREATE_DBV3
Parameter an SqlConfigDataSource() übergeben. Hier ist der Code von JetSqlUtil.cs meines OSS Projekt genommen PlaneDisaster.NET:
#region PInvoke
private enum ODBC_Constants : int {
ODBC_ADD_DSN = 1,
ODBC_CONFIG_DSN,
ODBC_REMOVE_DSN,
ODBC_ADD_SYS_DSN,
ODBC_CONFIG_SYS_DSN,
ODBC_REMOVE_SYS_DSN,
ODBC_REMOVE_DEFAULT_DSN,
}
private enum SQL_RETURN_CODE : int
{
SQL_ERROR = -1,
SQL_INVALID_HANDLE = -2,
SQL_SUCCESS = 0,
SQL_SUCCESS_WITH_INFO = 1,
SQL_STILL_EXECUTING = 2,
SQL_NEED_DATA = 99,
SQL_NO_DATA = 100
}
[DllImport("ODBCCP32.DLL",CharSet=CharSet.Unicode, SetLastError=true)]
private static extern int SQLConfigDataSource (int hwndParent, ODBC_Constants fRequest, string lpszDriver, string lpszAttributes);
[DllImport("ODBCCP32.DLL", CharSet = CharSet.Auto)]
private static extern SQL_RETURN_CODE SQLInstallerError(int iError, ref int pfErrorCode, StringBuilder lpszErrorMsg, int cbErrorMsgMax, ref int pcbErrorMsg);
#endregion
internal static string GetOdbcProviderName()
{
if (string.IsNullOrEmpty(OdbcProviderName))
{
var odbcRegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers", false);
var drivers = new List<string>(odbcRegKey.GetValueNames());
if (drivers.Contains("Microsoft Access Driver (*.mdb, *.accdb)"))
{
OdbcProviderName = "Microsoft Access Driver (*.mdb, *.accdb)";
}
else if (drivers.Contains("Microsoft Access Driver (*.mdb)"))
{
OdbcProviderName = "Microsoft Access Driver (*.mdb)";
}
else
{
//TODO: Condider checking for 32 versus 64 bit.
//TODO: Find a better exception type. http://stackoverflow.com/questions/7221703/what-is-the-proper-exception-to-throw-if-an-odbc-driver-cannot-be-found
throw new InvalidOperationException("Cannot find an ODBC driver for Microsoft Access. Please download the Microsoft Access Database Engine 2010 Redistributable. http://www.microsoft.com/download/en/details.aspx?id=13255");
}
}
/// <summary>
/// Creates an Access 2003 database. If the filename specified exists it is
/// overwritten.
/// </summary>
/// <param name="fileName">The name of the databse to create.</param>
/// <param name="version">The version of the database to create.</param>
public static void CreateMDB (string fileName, AccessDbVersion version = AccessDbVersion.Access2003) {
;
if (File.Exists(fileName)) {
File.Delete(fileName);
}
string command = "";
switch (version)
{
case AccessDbVersion.Access95:
command = "CREATE_DBV3";
break;
case AccessDbVersion.Access2000:
command = "CREATE_DBV4";
break;
case AccessDbVersion.Access2003:
command = "CREATE_DB";
break;
}
string attributes = String.Format("{0}=\"{1}\" General\0", command, fileName);
int retCode = SQLConfigDataSource
(0, ODBC_Constants.ODBC_ADD_DSN,
GetOdbcProviderName(), attributes);
if (retCode == 0)
{
int errorCode = 0 ;
int resizeErrorMesg = 0 ;
var sbError = new StringBuilder(512);
SQLInstallerError(1, ref errorCode, sbError, sbError.MaxCapacity, ref resizeErrorMesg);
throw new ApplicationException(string.Format("Cannot create file: {0}. Error: {1}", fileName, sbError));
}
}
Wenn Sie dies von einer 64-Bit-Version von SQL Server tun müssen, müssen Sie die 64-Bit-Version von Office 2010 oder die Microsoft Access Database Engine 2010 Redistributable installiert.
Ich versuche zu vermeiden, etwas wie dies zu tun: http://support.microsoft.com/kb/237575, weil dies etwas ist, das ich automatisieren muss. Nicht einmal sicher, ob es möglich ist, ohne dies zu tun. – leebrandt
Ich habe die Jet OleDb 3.51 Treiber DL'd und registriert sie in der Registrierung. Wenn ich versuche, den 3.51-Treiber für die Verbindung zu verwenden, bekomme ich "Der 'Microsoft.Jet.OLEDB.3.51' Provider ist nicht auf dem lokalen Rechner registriert." – leebrandt