EDB实际上不是真正意义上的DB,它是用嵌套结构体形式保存到二进制文件,因此它不支持SQL语句,微软提供了一大推CEMAPI操作EDB数据库
第一次接触EDB,想到的问题肯定都是有什么工具可以编辑、查看EDB库和表,很可惜,微软没有提供,BAIDU、GOOGLE也只能在国外网站找到一些介绍性文字,我至今也未找到这样的工具!
那这样的查看工具可以实现吗?通过几天的MSDN/BAIDU,个人感觉是可行的,下边我就用代码来演示如何枚举VOL文件所有数据库(EDB中数据库的概念实际就是表,一个VOL中可以有多个数据库),接着根据数据库找出表结构,最后枚举记录集
一、枚举VOL文件所有数据库
通过MAPI:CeFindFirstDatabaseEx、CeFindNextDatabaseEx可以做到
CEGUID m_VolGUID;
//打开VOL,通过CeMountDBVolEx 这个应该都会吧,省略
//.......
HANDLE hDbFind = CeFindFirstDatabaseEx(&m_VolGUID, 0);
//这个是个关键点,可以枚举出CEOID,知道这意味的什么吗? 在WINCE系统中,知道了CEOID就知道了一切!!! 可以参考MSDN
CEOID coid = CeFindNextDatabaseEx(hDbFind, &m_VolGUID);
//下边就是根据CEOID来获得EDB数据库详细信息
//包括数据库名、记录个数、排序方式、字段属性,神奇吧
CEOIDINFOEX info;
memset(&info, 0, sizeof(CEOIDINFOEX));info.wVersion = CEDBASEINFOEX_VERSION;iCeOidGetInfoEx2(&m_VolGUID, coid, &info);
//数据库名是什么呢?
info.infDatabase.szDbaseName 就是它了
二、枚举库中所有字段及属性
//通过MAPI:CeGetDatabaseProps
//首先知道了数据库名字,就可以打开数据库了,获得数据库句柄
m_hDB = CeOpenDatabaseInSession(m_hSession, &m_VolGUID, &coid, sName, NULL, 0,//CEDB_AUTOINCREMENT, NULL);
//获得字段个数CeGetDatabaseProps(m_hDB, &pid, NULL, NULL);
//分配本地内存
prgProps = (CEPROPSPEC*)LocalAlloc(LPTR, sizeof(CEPROPSPEC)*pid); for (int i = 0; i < pid; i++) { prgProps[i].wVersion = CEPROPSPEC_VERSION; prgProps[i].pwszPropName = new TCHAR[CEDB_MAXDBASENAMELEN]; prgProps[i].cchPropName = CEDB_MAXDBASENAMELEN; ZeroMemory(prgProps[i].pwszPropName, CEDB_MAXDBASENAMELEN); }
//获得字段信息
CeGetDatabaseProps(m_hDB, &pid, NULL, prgProps);
//EDB字段 分为名称、序号、类型
WORD wDataType = LOWORD((prgProps+i)->propid);WORD wId = HIWORD((prgProps+i)->propid);
prgProps[i].pwszPropName
三、获得数据库所有记录集
你有了表结构,这个网上列子一大推,就不重复了
下边列出1、2步实例代码:
//test CEOID coid; CEOIDINFOEX info; HANDLE hDbFind = CeFindFirstDatabaseEx(&m_VolGUID, 0); if(INVALID_HANDLE_VALUE != hDbFind) { WORD pid=0; CEPROPID *prgPropID; CEPROPSPEC *prgProps; int iNumRecord=0; int iNumSort=0; int iSize=0; FILETIME fti; SORTORDERSPECEX sort; while(1) { coid = CeFindNextDatabaseEx(hDbFind, &m_VolGUID); if(!coid) break; memset(&info, 0, sizeof(CEOIDINFOEX)); info.wVersion = CEDBASEINFOEX_VERSION; if(!CeOidGetInfoEx2(&m_VolGUID, coid, &info)) break; if(info.wVersion == CEDBASEINFOEX_VERSION && info.wObjType == OBJTYPE_DATABASE) { iNumRecord = info.infDatabase.dwNumRecords; iNumSort = info.infDatabase.wNumSortOrder; iSize = info.infDatabase.dwSize; memcpy(&fti, &info.infDatabase.ftLastModified, sizeof(FILETIME)); memcpy(&sort, &info.infDatabase.rgSortSpecs[0], sizeof(SORTORDERSPECEX)); //数据库名称 -- EDB中数据库概念对应表 WCHAR *sName = info.infDatabase.szDbaseName;
m_hDB = CeOpenDatabaseInSession(m_hSession, &m_VolGUID, &coid, sName, NULL, 0,//CEDB_AUTOINCREMENT, NULL); CeGetDatabaseProps(m_hDB, &pid, NULL, NULL);
prgProps = (CEPROPSPEC*)LocalAlloc(LPTR, sizeof(CEPROPSPEC)*pid); for (int i = 0; i < pid; i++) { prgProps[i].wVersion = CEPROPSPEC_VERSION; prgProps[i].pwszPropName = new TCHAR[CEDB_MAXDBASENAMELEN]; prgProps[i].cchPropName = CEDB_MAXDBASENAMELEN; ZeroMemory(prgProps[i].pwszPropName, CEDB_MAXDBASENAMELEN); } CeGetDatabaseProps(m_hDB, &pid, NULL, prgProps);
for(int i=0; i<pid; i++) { WORD wDataType = LOWORD((prgProps+i)->propid); WORD wId = HIWORD((prgProps+i)->propid); switch(wDataType) { case CEVT_BLOB://A BLOB structure { } break; case CEVT_BOOL: //A Boolean value { } break; case CEVT_FILETIME: //A FILETIME structure { } break; case CEVT_I2: //A 16-bit signed integer { } break; case CEVT_I4: //A 32-bit signed integer { } break; case CEVT_LPWSTR: //A null-terminated string { } break; case CEVT_R8: //A 64-bit float { } break; case CEVT_UI2: //A 16-bit unsigned integer { } break; case CEVT_UI4: //A 32-bit unsigned integer { } break; case CEVT_STREAM: //(EDB only) A large binary stream of data { } break; case CEVT_RECID: //(EDB only) A 128-bit GUID uniquely identifying a record { } break; case CEVT_AUTO_I4: //(EDB only) A 32-bit signed integer (auto-generated) { } break; case CEVT_AUTO_I8: //(EDB only) A 64-bit signed integer (auto-generated) { } break; } }
for (int i = 0; i < pid; i++) { delete [] prgProps[i].pwszPropName; } LocalFree((HLOCAL)prgProps); } } CloseHandle(hDbFind); } /
代码仅供参看,如果有不当之处,留言沟通,谢谢
如果转载,请注明出处