首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

動態生成 UDL 檔案類:CUdlFile 實作與 Unicode 編碼陷阱

     編輯:關於VC++

UDL 檔案格式解析

.udl (Universal Data Link) 實為 **Unicode 文字檔**,內容結構:

[oledb]
; Everything after this line is an OLE DB initstring
Provider=SQLOLEDB.1;Password=xxx;Persist Security Info=True;User ID=yyy;Initial Catalog=zzz;Data Source=server

關鍵限制:檔案開頭必須為 **BOM (Byte Order Mark) 0xFEFF**,否則 ADO 無法辨識。

CUldFile 類別設計

struct DBParam {
    char Server[20];
    char Database[20];
    char UserId[20];
    char Password[20];
};

class CUdlFile {
    DBParam m_dbParameter;
public:
    BOOL CreateUdlFile(LPCTSTR lpFileName);
    BOOL DeleteUdlFile(LPCTSTR lpFileName);
};

CreateUdlFile 完整實作

BOOL CUdlFile::CreateUdlFile(LPCTSTR lpFileName) {
    CFile fUdl;
    if (!fUdl.Open(lpFileName, CFile::modeCreate | CFile::modeWrite))
        return FALSE;
    
    // 1. 寫入 BOM (0xFEFF)
    WCHAR bom = 0xFEFF;
    fUdl.Write(&bom, sizeof(WCHAR));
    
    // 2. 寫入固定標頭 (Unicode)
    fUdl.Write(L"[oledb]", 14);          // 7 字元 * 2 bytes
    fUdl.Write(L"\r\n", 4);              // 2 字元 * 2 bytes
    fUdl.Write(L"; Everything after this line is an OLE DB initstring", 104); // 52 字元 * 2
    fUdl.Write(L"\r\n", 4);
    
    // 3. 格式化連線字串 (ANSI -> Unicode)
    CString s3;
    s3.Format(_T("Provider=SQLOLEDB.1;Password=%s;Persist Security Info=True;User ID=%s;Initial Catalog=%s;Data Source=%s"),
        m_dbParameter.Password, m_dbParameter.UserId,
        m_dbParameter.Database, m_dbParameter.Server);
    
    int m_Length = s3.GetLength();
    LPWSTR m_Buffer = (LPWSTR)malloc((m_Length + 1) * sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP, 0, s3, m_Length, m_Buffer, m_Length);
    fUdl.Write(m_Buffer, m_Length * 2); // 字元數 * 2 bytes
    free(m_Buffer);
    
    fUdl.Write(L"\r\n", 4);
    fUdl.Close();
    return TRUE;
}

DeleteUdlFile 簡單包裝

BOOL CUdlFile::DeleteUdlFile(LPCTSTR lpFileName) {
    return ::DeleteFile(lpFileName);
}

常見坑點與避雷指南

陷阱症狀解法
忘記寫入 BOMOpenUDLFile 失敗,錯誤「無效的連線字串」首寫 0xFEFF
用 CStdioFile 寫入預設為 ANSI,無 BOM用 CFile 二進位模式 + MultiByteToWideChar
Write 長度誤算檔案截斷或亂碼字元數 * sizeof(WCHAR) = *2
連線字串含特殊字元解析錯誤密碼含分號/等號時需雙引號包裹

進階應用:執行期產生 UDL 並開啟

CUdlFile udl;
udl.m_dbParameter.Server = _T("192.168.1.100");
udl.m_dbParameter.Database = _T("ERP");
udl.m_dbParameter.UserId = _T("sa");
udl.m_dbParameter.Password = _T("P@ssw0rd");

CString udlPath = _T("C:\\Temp\\Runtime.udl");
if (udl.CreateUdlFile(udlPath)) {
    CAdoConnection conn;
    if (conn.OpenUDLFile(udlPath)) {
        // 連線成功,可直接操作
    }
    // 用完可刪除
    udl.DeleteUdlFile(udlPath);
}

適合:安裝程式自動配置、多資料庫切換、避免硬編碼連線字串、部署時由使用者輸入參數產生專屬 UDL。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved