“故事的其余部分”在下面讲述了所有血淋淋的细节,但话说回来,它归结为:
SQLCE2.0(包含在sqlce.wce4.armv4.CAB中)似乎安装在我的应用程序运行的设备上;源项目引用SqlServerCe,运行时版本为v2.0.50727,版本为3.5.1.0
这是匹配还是错配?如果是后者,我需要在我的项目中引用哪个版本的SqlServerCe.dll?
其他血淋淋的故事
我的Windows应用程序在尝试打开SQL (.SDF)文件时失败了;以前的一个底层问题显然与版本控制(调用SqlCeEngine.Upgrade() )连接(调用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;...so,不管是util还是应用程序本身似乎都没有创建SqlCe数据库(HHSDB.SDF) --该应用程序只是定位.SDF文件,然后从它/写到它。
当应用程序创建一个表(如上面的CreateSettingsTable() )和类似的活动时,它将使用一个SqlCe DLL来完成这个任务,而且由于ctacke说该DLL的版本(设备上的DLL )必须与该项目的源代码相匹配,实际上应该在设备上有一个,但是由于我在设备上没有看到任何SqlCe DLL,所以不可能验证设备和项目构建环境上的版本是否匹配.
具体而言:设备上没有sqlserverce.dll;是否需要查找其他文件?缺乏这个DLL本身不一定是一个问题,否则我将无法通过以下代码(我这样做):
engine = new SqlCeEngine(conStr);项目中引用的System.Data.SqlServerCe DLL是运行时版本"v2.0.50727",版本"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版本2...does 2安装cab文件,对应于应用程序引用的SqlServerCE DLL中的“运行时版本”或“版本”?
我认为这些计程车应该被展开/包含SqlCe DLL,但是,正如我所写的,在运行这个设置util之后,我看不到设备上的任何计程车(这似乎很好)。
因此,总结和重申:
SQLCE2.0(包含在sqlce.wce4.armv4.CAB中)似乎安装在我的应用程序运行的设备上;源项目引用SqlServerCe,运行时版本为v2.0.50727,版本为3.5.1.0
这是匹配还是错配?如果是后者,我需要在我的项目中引用哪个版本的SqlServerCe.dll?
更新
这些是设备上的一些文件:

更新2
很明显,从表面上看,基于文件名,这些文件是3.5版本,我在JetBrains‘dotPeek中打开它们,试图验证这一点,但这些DLL的“(不支持)”,我得到了“(不支持)”。
在Reflector中尝试同样的事情给了我更多的信息:‘C:\Bla\sqlceca35.dll’不是一个.NET模块。
发布于 2014-05-06 22:26:39
是的,你错配了。
您有一个数据库文件,在内部表明它是SQLCompact2.0文件。
您有一个版本为3.5.1的System.Data.SqlServerCe.dll程序集。“运行时版本”指的是它所针对的CF运行时,所以它是针对2.0运行时构建的--并不意味着它本身就是2.0。这就是混乱的地方--你一直在命名两个版本,而一个程序集只有一个版本。
这是我的怀疑,因为你打电话给Upgrade()是在SQLCompact2.0中甚至不存在。
如果您想在原始数据库的状态下打开原始数据库,并且允许原始创建者仍然可以访问它(必须有创建它的代码,或者它已经部署在CAB文件中,这是不可能发生的),那么我再次重申,您必须使用相同版本的SQL来实现它。
在您的具体情况下,这意味着您应该执行以下操作:
您不需要调用Upgrade(),除非您想要使它成为3.5个数据库,此时您不能返回,而且每次运行时都会尝试升级,我怀疑这也是您想要的。该方法一般用于实用程序或一次性使用。
无论您的PC上有多少其他版本的程序集,实际上您也可以在设备上使用倍数。重要的是,您在项目引用中的内容,即应用程序所链接的内容,是应用程序实际执行时由应用程序在设备上加载的相同的DLL。
通常,我会做两件事来确保这种情况的发生:
https://stackoverflow.com/questions/23505211
复制相似问题