下面讲述了“故事的其余部分”的所有血腥细节,但切入正题,归结为:
SQLCE 2.0(包含在 sqlce.wce4.armv4.CAB 中)似乎安装在我的应用程序运行的设备上;源项目引用运行时版本为 v2.0.50727 和版本为 3.5.1.0 的 SqlServerCe
这是匹配还是不匹配?如果是后者,我需要在我的项目中引用哪个版本的 SqlServerCe.dll?
血腥故事的其余部分
我的 Windows CE 应用程序在尝试打开 SQL CE (.SDF) 文件时失败;尽管一个潜在的早期问题显然与版本控制有关(没有双关语)(调用 SqlCeEngine.Upgrade() 让我过去了),错误消息现在表明密码问题。看到这个
但是我看不到在表上设置密码的位置 - 也看不到指定 SQLCE 版本的位置。
我们有一个安装实用程序,可以在手持设备上安装此应用程序以及必要的辅助文件。为了弄清楚这两个应用程序(正确的安装应用程序)在版本控制和密码方面到底做了什么,我在两个代码库中搜索了“SDF”和“SQLCE”,这是我发现的*:
设置实用程序中对“SDF”的唯一引用是:
{_T("OpenNETCF.SDF.WCE4.ARMV4.CAB"),_T("OpenNETCF SDF v1.4"),(DWORD)0,true},
应用程序本身中对“SDF”的唯一引用不会创建SqlCe(“SDF”)数据库。如果确实存在此类引用,它们会查找已存在的特定 SDF 文件,如下所示:
filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "HHSDB.SDF");
然后引擎数据库引擎被实例化和升级,并有条件地创建一个数据库(在我的例子中,文件存在,所以不调用 CreateDatabase()):
engine = new SqlCeEngine(conStr);
engine.Upgrade(conStr); // <= Recommended by ctacke
if (File.Exists(filename))
{
MessageBox.Show(string.Format("file {0} exists", filename)); // TODO: Comment out or remove
}
else
{
engine.CreateDatabase();
}
安装实用程序中对“SQLCE”的唯一引用是:
0)
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by HHSetupCon.rc
//
. . .
#define IDR_NETCF 103
#define IDR_SQLCLIENT 104
#define IDR_SQLCEDEV 105
#define IDR_SQLCE 106
. . .
1)
IDR_SQLCLIENT BIN "J:\\sql.wce4.armv4.zip"
IDR_SQLCEDEV BIN "J:\\sqlce.dev.wce4.armv4.zip"
IDR_SQLCE BIN "J:\\sqlce.wce4.armv4.zip"
2)
{_T("sqlce.dev.wce4.armv4.CAB"),_T("Microsoft SQLCE 2.0 Dev"),IDR_SQLCEDEV,false},
{_T("sqlce.wce4.armv4.CAB"),_T("Microsoft SQLCE 2.0"),IDR_SQLCE,false},
应用程序本身对“SQLCE”的引用会创建或查询 SDF 表,例如:
// This creates a table (a *table*, not the database itself)
public static void CreateSettingsTable()
{
try
{
string sqlddl =
"create table platypus_settings (setting_id int identity (1,1) Primary key, setting_name nvarchar(40) not null, setting_value nvarchar(63))";
DBConnection.GetInstance().DBCommand(sqlddl, false);
}
catch (SqlCeException sqlcex)
{
SSCS.ExceptionHandler(sqlcex, "DBUtils.CreateSettingsTable");
}
catch (Exception ex)
{
SSCS.ExceptionHandler(ex, "DBUtils.CreateSettingsTable");
}
}
注意:DBConnection 是一个自定义类,其中包含一些 SqlCe* 成员:
SqlCeConnection objCon = null;
SqlCeEngine engine;
public SqlCeTransaction SqlTrans;
...因此,实用程序和应用程序本身似乎都没有创建SqlCe数据库(HHSDB.SDF) - 应用程序只需找到 .SDF 文件,然后从中读取/写入。
似乎当应用程序创建一个表(如上面的 CreateSettingsTable() )和类似活动时,它会使用 SqlCe DLL 来执行此操作,并且由于 ctacke 说该 DLL 的版本(设备上的那个)有与项目源代码相关的那个,实际上应该在设备上有一个,但是由于我在设备上没有看到任何SqlCe DLL,因此无法验证设备上的版本和项目构建环境是否匹配。 ..
具体来说:设备上没有sqlserverce.dll;是我应该寻找的其他文件吗?缺少此 DLL 本身一定不是问题,否则我将无法通过以下代码(我会这样做):
engine = new SqlCeEngine(conStr);
项目中引用的 System.Data.SqlServerCe DLL 为 Runtime Version "v2.0.50727", Version "3.5.1.0"
安装项目没有这样的引用,AFAICT(它是一个 C++ 项目)。但是,它确实有以下代码:
{_T("sqlce.dev.wce4.armv4.CAB"),_T("Microsoft SQLCE 2.0 Dev"),IDR_SQLCEDEV,false},
{_T("sqlce.wce4.armv4.CAB"),_T("Microsoft SQLCE 2.0"),IDR_SQLCE,false},
所以它为 SQL CE 版本 2 安装 cab 文件...这里的版本 2 是否与应用程序引用的 SqlServerCE DLL 中的“运行时版本”或“版本”相对应?
我认为这些 cab 应该被扩展/包含 SqlCe DLL [s] 但是,正如我所写的,在运行这个 setup util 之后我在设备上看不到任何东西(这似乎工作正常)。
所以,总结和重申:
SQLCE 2.0(包含在 sqlce.wce4.armv4.CAB 中)似乎安装在我的应用程序运行的设备上;源项目引用运行时版本为 v2.0.50727 和版本为 3.5.1.0 的 SqlServerCe
这是匹配还是不匹配?如果是后者,我需要在我的项目中引用哪个版本的 SqlServerCe.dll?
- “入境口岸的警察说……” - 对不起,我忍不住(或者不想更喜欢它)
更新
这些是设备上的一些文件:
更新 2
尽管如此,表面上很明显,根据文件名,这些是 3.5 版,我在 JetBrains 的 dotPeek 中打开它们以试图验证这一点,但结果平淡无奇 - 我得到这些 DLL 的“(不支持)”。
在 Reflector 中尝试同样的事情给了我更多信息:“'C:\Bla\sqlceca35.dll' 不是 .NET 模块。”