OleDbConnection.Open() 引发的 AccessViolationException

AccessViolationException thrown by OleDbConnection.Open()

尝试在我的 OleDbConnection 变量上使用 .Open() 方法时出现 System.AccessViolationException 错误。但是,令人困惑的是,当我 运行 我的代码在另一台计算机上时,它似乎并没有发生。

我的代码用于我希望 运行在服务器上运行的服务。当我在我的个人计算机上 运行 它似乎工作正常,但当我在服务器上尝试 运行 时它抛出 AccessViolationException 错误。

代码版本:

我的代码:

    internal static bool CreateMDB(MySchemaClass schema, string filePath)
    {
        OleDbConnection conn = null;
        bool status = true;
        string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}", filePath);

        try
        {
            // Setup new file
            catalog.Create(connectionString);
            ((ADODB.Connection)catalog.ActiveConnection).Close();
            conn = new OleDbConnection(connectionString);
            conn.Open(); // <-- Error occurs here

            // Write to new file
            WriteDataToFile(schema, conn);
        }
        catch (Exception ex)
        {
            status = false;
        }
        finally
        {
            if (conn != null)
                conn.Close();
        }
        return status;
    }

堆栈跟踪:

到目前为止我找到的最好的线索是 this post,但我对如何从那个起点继续前进有点模糊。

要以编程方式创建 Access 数据库,请执行以下操作

添加对 Microsoft ADO Ext. 6.0 for DDL and Security

的引用
  • 在 VS 菜单中,单击 项目
  • Select 添加引用
  • 单击 COM
  • 检查 Microsoft ADO Ext. 6.0 用于 DDL 和安全

CreateAccessDatabase

public static string CreateAccessDatabase(string fullyQualifiedAccessFilename, string dbPassword = "")
{
    string connectionString = String.Format(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0}", fullyQualifiedAccessFilename);

    if (String.IsNullOrEmpty(fullyQualifiedAccessFilename))
    {
        throw new Exception("Error (CreateAccessDatabase) - Database filename is null or empty.");
    }

    if (!String.IsNullOrEmpty(dbPassword))
    {
        connectionString = String.Format(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0};Jet OLEDB:Database Password='{1}'", fullyQualifiedAccessFilename, dbPassword);
    }
    
    //create new instance
    ADOX.Catalog cat = new ADOX.Catalog();

    //create Access database
    cat.Create(connectionString);

    //close connection
    cat.ActiveConnection.Close();

    //release COM object
    System.Runtime.InteropServices.Marshal.ReleaseComObject(cat);
    GC.Collect();

    cat = null;

    return String.Format("Database created '{0}'", fullyQualifiedAccessFilename);
}

用法:

string result = string.Empty;

SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Access Database 2000-2003 (*.mdb)|*.mdb|Access Database 2007 (*.accdb)|*.accdb";

if (sfd.ShowDialog() == DialogResult.OK)
{
    //create Access database
    result = CreateAccessDatabase(sfd.FileName);
}

以编程方式在 Access 数据库中创建 table:

添加 using 语句:

using System.Data.OleDb;

CreateTableProduct:

public static int CreateTableProduct(string fullyQualifiedAccessFilename, string dbPassword = "")
{
    int result = 0;

    string connectionString = String.Format(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0}", fullyQualifiedAccessFilename);

    if (!String.IsNullOrEmpty(dbPassword))
    {
        connectionString = String.Format(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = {0};Jet OLEDB:Database Password='{1}'", fullyQualifiedAccessFilename, dbPassword);
    }

    string sqlText = string.Empty;
    sqlText = "CREATE TABLE Product ";
    sqlText += "(ID AUTOINCREMENT not null primary key,";
    sqlText += " Name varchar(50) not null,";
    sqlText += " Price currency, Quantity integer);";

    using (OleDbConnection con = new OleDbConnection(connectionString))
    {
        //open connection
        con.Open();

        using (OleDbCommand sqlCmd = new OleDbCommand(sqlText, con))
        {
            //execute command
            result = sqlCmd.ExecuteNonQuery();
        }
    }

    return result;
}

资源:

这个问题的答案是我的服务器缺少我个人计算机上的一些文件,只需要安装正确的文件。

在这种情况下缺少的部分是 Microsoft Access Database Engine 2016 Redistributable,我最终找到了它 here。 运行 我服务器上的可执行文件获得了所需的文件,之后一切正常。