我使用CDatabase該類打開一個ACCDBAccess 資料庫。司機是:_T("Microsoft Access Driver (*.mdb, *.accdb)")。
我可以打開并使用資料庫OK(已經這樣做了很多年了):
if (DatabaseExist(m_strMDBPath))
{
// AJT v10.5.0 Take into account the DB mode
strDriver = GetJETDriverEx(bAccDbMode);
// AJT v10.5.0 Take into account the DB password (decrypted!)
strDBConnectString.Format(_T("Driver={%s};DBQ=%s;Pwd=%s"),
(LPCTSTR)strDriver, (LPCTSTR)m_strMDBPath,
(LPCTSTR)m_toolsMSA.DecryptDatabasePassword(strPassword));
try
{
//OutputDebugString(L"DB Open - Begin\n");
if (m_Database.OpenEx(strDBConnectString, CDatabase::noOdbcDialog))
{
//OutputDebugString(L"DB Open - End\n");
}
}
catch (CDBException* e)
{
// If a database exception occurred, show error msg
AfxMessageBox(L"Database error: " e->m_strError);
}
}
我在以編程方式壓縮資料庫時遇到問題。以前我使用的是 DAO:
Microsoft.Office.Interop.Access.Dao
但這需要安裝 Access 2013 Runtime。而且我不想再安裝它了,因為我的 PC 上安裝了 Access 2016。
執行壓縮的代碼使用了以下DBEngine命令:
Microsoft.Office.Interop.Access.Dao.DBEngine objDbEngine = new Microsoft.Office.Interop.Access.Dao.DBEngine();
但是現在我需要一種新的方法來壓縮資料庫,因為我不再擁有 DAO 參考。最終用戶可能沒有安裝 Access 2016,但我會告訴他們安裝 Access 2016 運行時。
我可以使用什么替代方法在我的 MFC 專案中以編程方式壓縮此 ACCDB?
請注意,我有一個底層 C# .Net DLL 工具,因此如果它比 C 更容易,我可以將任何此類壓縮添加到該 C# 庫。
這就是我之前使用需要 2013 運行時的 DAO 的方式:
我試過這個:
#pragma once
#import "C:\\Program Files\\Microsoft Office\\root\\Office16\\ACEDAO.DLL" named_guids rename("EOF", "ACEDAO_EOF")
static void Test(CString strDB, CString strDbCompacted)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
DAO::_DBEngine* pDBEngine = NULL;
HRESULT hr = CoCreateInstance(__uuidof(DAO::DBEngine), NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (LPVOID*)&pDBEngine);
if (SUCCEEDED(hr) && pDBEngine)
{
_bstr_t bstrDatabase = strDB.AllocSysString();
_bstr_t bstrDatabaseCompacted = strDbCompacted.AllocSysString();
try
{
pDBEngine->CompactDatabase(bstrDatabase, bstrDatabaseCompacted, L";pwd=xxx");
}
catch (_com_error& e)
{
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
WCHAR wsBuffer[255];
wsprintf(wsBuffer, L"Source : %s\nDescription : %s", (LPCTSTR)bstrSource, (LPCTSTR)bstrDescription);
MessageBox(NULL, wsBuffer, L"Error", MB_OK | MB_ICONSTOP);
}
pDBEngine->Release();
}
}
但它失敗了,甚至沒有到達catch處理程式。
我只是在尋找一種簡單的方法來支持緊湊,更改 MDB 和 ACCDB 的密碼......我什至嘗試添加 acedao.dll 作為對 C# 控制臺專案的參考,但它不會接受它。
如評論中所述,我嘗試使用后期系結。這是功能:
public void CompactAccessDatabase(string strSourceDB, string strTargetDB, string strPassword)
{
try
{
dynamic dbEngine = Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DbEngine"));
string strDecryptedPassword = "";
if(!string.IsNullOrEmpty(strPassword))
{
if (!DecryptDatabasePassword(strPassword, ref strDecryptedPassword))
{
SimpleLog.Log("DecryptDatabasePassword returned false");
}
strDecryptedPassword = "pwd=" strDecryptedPassword;
}
dbEngine.CompactDatabase(strSourceDB, strTargetDB, null, null, strDecryptedPassword);
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
}
但我遇到了一個例外:
<LogEntry Date="2022-05-26 13:06:49" Severity="Exception" Source="MSAToolsLibrary.MSAToolsLibraryClass.CompactAccessDatabase" ThreadId="1">
<Exception Type="System.ArgumentNullException" Source="System.Activator.CreateInstance">
<Message>Value cannot be null.
Parameter name: type</Message>
<StackTrace> at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at MSAToolsLibrary.MSAToolsLibraryClass.CompactAccessDatabase(String strSourceDB, String strTargetDB, String strPassword) in D:\My Programs\2022\MSAToolsLibrary\MSAToolsLibrary\MSAToolsLibraryClass.cs:line 1649</StackTrace>
</Exception>
</LogEntry>
https://stackoverflow.com/a/29252649/2287576
uj5u.com熱心網友回復:
根據鏈接答案中提到的評論和原則,我最終能夠提出此代碼,適用于我的 64 位構建:
public void CompactAccessDatabase(string strSourceDB, string strTargetDB, string strPassword)
{
try
{
dynamic dbEngine = Activator.CreateInstance(Type.GetTypeFromProgID("DAO.DBEngine.120"));
string strDecryptedPassword = "";
string strDBConnectionString = "";
if(!string.IsNullOrEmpty(strPassword))
{
if (!DecryptDatabasePassword(strPassword, ref strDecryptedPassword))
{
SimpleLog.Log("DecryptDatabasePassword returned false");
}
strDBConnectionString = ";pwd=" strDecryptedPassword;
}
dbEngine.CompactDatabase(strSourceDB, strTargetDB, null, null, strDBConnectionString);
}
catch (Exception ex)
{
SimpleLog.Log(ex);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/482478.html
