在未安装 Access 的情况下使用 C# 在 运行 时间内压缩和修复 Access 数据库
Compact and repair Access DataBase in run time using C# without Access installed
我编写的程序应该 运行 在很多机器上
我没有在机器上安装 Access 但是我有一个在它们上使用的访问数据库
当我从这个 Access 数据库中写入和删除数据时,它的大小会变大,所以每隔几天我就必须压缩它们并缩小大小
这是我使用的代码
public void Compacting()
{
try
{
Microsoft.Office.Interop.Access.Application application = new Microsoft.Office.Interop.Access.Application();
string dbName = "";
try
{
dbName = ConfigurationManager.ConnectionStrings["LocalPulserDB"].ConnectionString.Split("Data Source=").Last().Split(";").First();
}
catch (Exception ex)
{
string localDbError = "DataBase location is incorrect ";
System.Windows.MessageBox.Show(localDbError);
Environment.Exit(1);
}
CompactAndRepair(dbName, application);
}
catch (Exception ex)
{
try
{
LocalPulserDBManagerInstance.WriteLog(ex.StackTrace, ex.Message);
}
catch (Exception)
{
}
}
}
private void CompactAndRepair(string accessFile, Microsoft.Office.Interop.Access.Application app)
{
string tempFile = Path.Combine(Path.GetDirectoryName(accessFile),
Path.GetRandomFileName() + Path.GetExtension(accessFile));
app.CompactRepair(accessFile, tempFile, true);
app.Visible = false;
FileInfo temp = new FileInfo(tempFile);
temp.CopyTo(accessFile, true);
temp.Delete();
}
但是我遇到了下一个错误:
{"Retrieving the COM class factory for component with CLSID {73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE))."}
我能做什么?
Interop 要求在代码 运行 所在的计算机上安装 Office,我怀疑您将无法使用该方法执行压缩和修复。
但是您可以使用这个独立的工具,"Jet compact utility":
https://docs.microsoft.com/en-us/office/troubleshoot/access/jet-compact-utility-download
您不需要甚至不想创建一个完整的实例来访问just compact。 (甚至使用 + 从 tables.
中提取数据
设置对 ACE 数据库引擎的引用。这样您就可以提取和使用数据,而不必自动(创建)像 Access 这样的相当繁重的应用程序对象。如果您确实创建了一个完整的 Access 实例,那么 VBA 代码和启动表单 运行 之类的东西(不仅如此糟糕,因为现在您有一个隐藏的 UI - 但您可以不回答提示,更糟糕的是,启动代码可能会启动一个表单,该表单将打开 table,然后您无法压缩,直到所有 table 都关闭。
IN vb.net 代码,这将压缩:
Dim ACEEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine
Dim strDatabase As String = "c:\test\test44.accdb"
' you always compact to a copy - you cannot compact "over" the existing database
Dim strTempDB As String = "c:\test\temp.accdb"
Debug.Print("starting compact")
Try
ACEEngine.CompactDatabase(strDatabase, strTempDB)
Debug.Print("compact done")
Catch ex As Exception
Debug.Print(Err.Description)
End Try
注意:
您可以按照上面的方法检查错误代码,因为如果数据库中有任何其他用户,则不会发生压缩。
上面的输出是否是其他人打开了数据库?
starting compact
Exception thrown: 'System.Runtime.InteropServices.COMException' in ACETest.exe
You attempted to open a database that is already opened by user 'Admin' on machine
'ALBERTKALLAL-PC'. Try again when the database is available.
所以,抓住错误。如上所示,您需要对
的互操作引用
C:\Program Files (x86)\Microsoft Visual Studio 12.0\
Visual Studio Tools for Office\PIA\Office14\
Microsoft.Office.interop.access.dao.dll
只需检查err.Number是否为0。如果发生压缩,那么您可以删除或更好地重命名原始数据库,然后将“temp”数据库重命名回原始名称。 (来自 Access UI 的压缩 + 修复在幕后执行此操作,实际上在压缩过程中永远不会覆盖原始文件,因为它可能会失败或无法工作)。您可以在尝试压缩之前尝试检查现有的 .ldb 文件(一个锁定文件),但压缩过程检查 + 要求您对该文件有 100% 的独占使用权,如果压缩无法独占使用文件,然后按照上面的方式吐出一条错误消息。
因此,只需将程序集引用添加到您的项目中即可。您还应该将您的 .net 项目强制为 x86,而不是将其保留为“ANY CPU”。
以上内容无需安装 Access 即可使用。但是,您需要安装 JET 或 ACE 数据引擎。默认情况下,JET 引擎安装在 windows 的所有副本上 - 但仅适用于 mdb 文件。如果您需要压缩并使用 accDB 文件,那么您将必须安装 ACE 数据库引擎 - 但它占用的空间要小得多,然后安装整个 Access 副本或 运行 时间(两者都大约大小相同,而且相当大。如上所述,您不需要在计算机上安装 Access。
编辑
您可以从这里找到并安装一个 ACE 版本:
https://www.microsoft.com/en-us/download/details.aspx?id=54920
注意上面,你有两个选择。 (x32 或 x64 - 所以你必须安装你想要的版本。这也表明你需要两个版本的 .net 代码或者你可以找到一种快捷方式来启动“任何”cpu 以 x32 或 x64 启动- 如果您选择“任何cpu”而不是强制.net 项目(并提供两个版本的我在下面的示例 link 中所做的项目)。
我在这里有一个可用的 .net(微型).exe 文件,它允许您 运行 作为 x32 或 x64,因此您可以快速检查您安装的 ACE 版本。
我编写的程序应该 运行 在很多机器上
我没有在机器上安装 Access 但是我有一个在它们上使用的访问数据库
当我从这个 Access 数据库中写入和删除数据时,它的大小会变大,所以每隔几天我就必须压缩它们并缩小大小
这是我使用的代码
public void Compacting()
{
try
{
Microsoft.Office.Interop.Access.Application application = new Microsoft.Office.Interop.Access.Application();
string dbName = "";
try
{
dbName = ConfigurationManager.ConnectionStrings["LocalPulserDB"].ConnectionString.Split("Data Source=").Last().Split(";").First();
}
catch (Exception ex)
{
string localDbError = "DataBase location is incorrect ";
System.Windows.MessageBox.Show(localDbError);
Environment.Exit(1);
}
CompactAndRepair(dbName, application);
}
catch (Exception ex)
{
try
{
LocalPulserDBManagerInstance.WriteLog(ex.StackTrace, ex.Message);
}
catch (Exception)
{
}
}
}
private void CompactAndRepair(string accessFile, Microsoft.Office.Interop.Access.Application app)
{
string tempFile = Path.Combine(Path.GetDirectoryName(accessFile),
Path.GetRandomFileName() + Path.GetExtension(accessFile));
app.CompactRepair(accessFile, tempFile, true);
app.Visible = false;
FileInfo temp = new FileInfo(tempFile);
temp.CopyTo(accessFile, true);
temp.Delete();
}
但是我遇到了下一个错误:
{"Retrieving the COM class factory for component with CLSID {73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9} failed due to the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE))."}
我能做什么?
Interop 要求在代码 运行 所在的计算机上安装 Office,我怀疑您将无法使用该方法执行压缩和修复。
但是您可以使用这个独立的工具,"Jet compact utility": https://docs.microsoft.com/en-us/office/troubleshoot/access/jet-compact-utility-download
您不需要甚至不想创建一个完整的实例来访问just compact。 (甚至使用 + 从 tables.
中提取数据设置对 ACE 数据库引擎的引用。这样您就可以提取和使用数据,而不必自动(创建)像 Access 这样的相当繁重的应用程序对象。如果您确实创建了一个完整的 Access 实例,那么 VBA 代码和启动表单 运行 之类的东西(不仅如此糟糕,因为现在您有一个隐藏的 UI - 但您可以不回答提示,更糟糕的是,启动代码可能会启动一个表单,该表单将打开 table,然后您无法压缩,直到所有 table 都关闭。
IN vb.net 代码,这将压缩:
Dim ACEEngine As New Microsoft.Office.Interop.Access.Dao.DBEngine
Dim strDatabase As String = "c:\test\test44.accdb"
' you always compact to a copy - you cannot compact "over" the existing database
Dim strTempDB As String = "c:\test\temp.accdb"
Debug.Print("starting compact")
Try
ACEEngine.CompactDatabase(strDatabase, strTempDB)
Debug.Print("compact done")
Catch ex As Exception
Debug.Print(Err.Description)
End Try
注意: 您可以按照上面的方法检查错误代码,因为如果数据库中有任何其他用户,则不会发生压缩。
上面的输出是否是其他人打开了数据库?
starting compact
Exception thrown: 'System.Runtime.InteropServices.COMException' in ACETest.exe
You attempted to open a database that is already opened by user 'Admin' on machine
'ALBERTKALLAL-PC'. Try again when the database is available.
所以,抓住错误。如上所示,您需要对
的互操作引用C:\Program Files (x86)\Microsoft Visual Studio 12.0\
Visual Studio Tools for Office\PIA\Office14\
Microsoft.Office.interop.access.dao.dll
只需检查err.Number是否为0。如果发生压缩,那么您可以删除或更好地重命名原始数据库,然后将“temp”数据库重命名回原始名称。 (来自 Access UI 的压缩 + 修复在幕后执行此操作,实际上在压缩过程中永远不会覆盖原始文件,因为它可能会失败或无法工作)。您可以在尝试压缩之前尝试检查现有的 .ldb 文件(一个锁定文件),但压缩过程检查 + 要求您对该文件有 100% 的独占使用权,如果压缩无法独占使用文件,然后按照上面的方式吐出一条错误消息。
因此,只需将程序集引用添加到您的项目中即可。您还应该将您的 .net 项目强制为 x86,而不是将其保留为“ANY CPU”。
以上内容无需安装 Access 即可使用。但是,您需要安装 JET 或 ACE 数据引擎。默认情况下,JET 引擎安装在 windows 的所有副本上 - 但仅适用于 mdb 文件。如果您需要压缩并使用 accDB 文件,那么您将必须安装 ACE 数据库引擎 - 但它占用的空间要小得多,然后安装整个 Access 副本或 运行 时间(两者都大约大小相同,而且相当大。如上所述,您不需要在计算机上安装 Access。
编辑
您可以从这里找到并安装一个 ACE 版本: https://www.microsoft.com/en-us/download/details.aspx?id=54920
注意上面,你有两个选择。 (x32 或 x64 - 所以你必须安装你想要的版本。这也表明你需要两个版本的 .net 代码或者你可以找到一种快捷方式来启动“任何”cpu 以 x32 或 x64 启动- 如果您选择“任何cpu”而不是强制.net 项目(并提供两个版本的我在下面的示例 link 中所做的项目)。
我在这里有一个可用的 .net(微型).exe 文件,它允许您 运行 作为 x32 或 x64,因此您可以快速检查您安装的 ACE 版本。