如何部署Microsoft SQL Server Compact4.0
(目前版本为4.0)是:
一个免费的嵌入式数据库,软件开发人员可以用来构建Windows桌面应用程序。它占用空间小,并且支持在应用程序文件夹中私有部署其二进制文件。
但是你是如何部署它的呢?
问题是,除非注册了ADO OLEdb提供程序,否则不能使用它。注册OLEdb提供程序必须作为管理员完成。这意味着对于非管理员的用户来说,将失败。
SQLServerCompact4.0附带一个redist_enu.txt文件:
列出的.exe文件每个都将其封闭的组件安装到目标计算机上的特定位置。这有助于确保可使用性和技术支持。这些.dll文件中包含的.exe文件在这个redist.txt中也是单独可用的。但是,这些单独的.dlls的发行版可能会导致服务性问题。有关更多细节,请参见http://go.microsoft.com/fwlink/?LinkId=94589 通过BreadCrumb进行私有部署检测:不支持仅通过本机堆栈进行私有部署,并通过Assembly.LoadFrom()、.local文件或使用DLL/COM重定向策略显式加载Server压缩程序集,并可能导致服务性问题。有关更多信息,请参见http://support.microsoft.com/kb/835322和http://msdn2.microsoft.com/en-us/library/aa375142.aspx Microsoft SQL Server Compact4.0 SSCERuntime_x86-ENU.exe SSCERuntime_x86-DEU.exe SSCERuntime_x86-FRA.exe SSCERuntime_x86-JPN.exe SSCERuntime_x86-RUS.exe SSCERuntime_x86-ESN.exe SSCERuntime_x86-ITA.exe SSCERuntime_x86-KOR.exe SSCERuntime_x86-CHT.exe SSCERuntime_x86-CHS.exe SSCERuntime_x64-ENU.exe SSCERuntime_x64-DEU.exe SSCERuntime_x64-FRA.exe SSCERuntime_x64-JPN.exe SSCERuntime_x64-RUS.exe SSCERuntime_x64-ESN.exe SSCERuntime_x64-ITA.exe SSCERuntime_x64-KOR.exe SSCERuntime_x64-CHT.exe SSCERuntime_x64-CHS.exe sqlcese40.dll sqlceqp40.dll sqlceoledb40.dll sqlceca40.dll sqlceme40.dll sqlcecompact40.dll sqlceer40en.dll sqlceer40cn.dll/sqlceer40zh-CHS.dll sqlceer40de.dll sqlceer40es.dll sqlceer40fr.dll sqlceer40it.dll sqlceer40ja.dll sqlceer40ko.dll sqlceer40tw.dll/sqlceer40zh-CHT.dll sqlceer40ru.dll System.Data.SqlServerCe.dll System.Data.SqlServerCe.Entity.dll
但是它没有提供任何关于如何重新分发SQLServerCompact4.0的信息。
在无文档的Program Files文件夹周围随意拼写,我找到了7个dll:
C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\
sqlceoledb40.dll
sqlceqp40.dll
sqlcese40.dll
sqlceca40.dll
sqlcecompact40.dll
sqlceer40EN.dll
sqlceme40.dll注意:还有一些带有更多dll的子文件夹
我尝试将这7个dll复制到一个文件夹中,并尝试使用ADO连接打开连接字符串
Provider=Microsoft.SQLSERVER.CE.OLEDB.4.0;Data Source="store.sdf"但是它在0x80004005 Unspecified error中失败了
我试着给小部件起泡,但它使小部件发亮。
发布于 2012-05-29 14:04:39
我创造了解决方案。
由7个dll组成:
sqlceme40.dll无文档的、本机的、平面的API库( .net System.Data.SqlServerCe.dll程序集是围绕这个dll的包装器)sqlceca40.dll实现Engine、Replication、Error和其他几个COM对象的COM dllsqlceoledb40.dll实现OLEdb提供程序的COM dll (允许使用ADO)sqlcese40.dll未知sqlceqp40.dll未知sqlcecompact40.dll未知sqlceer40en.dll未知简单地发布这些dll的问题是,其中两个是COM对象。COM对象dll需要注册,例如:
>regsvr32 sqlceca40.dll
>regsvr32 sqlceoledb40.dll问题是注册COM对象需要管理权限(使用全局解决方案解决局部问题)。这意味着您的用户将
幸运的是,从2001年Windows开始,微软解决了这个COMmon问题:免费注册。
首先,您将声明您的应用程序在4.0上有一个"dependancy"。要做到这一点,您可以编写程序集清单:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="client"
type="win32"
/>
<description>Hyperion Pro</description>
<!-- We have a dependancy on SQL Server CE 4.0 -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.SQLSERVER.CE.4.0"
version="4.0.0.0" processorArchitecture="x86"
/>
</dependentAssembly>
</dependency> <!-- We are high-dpi aware on Windows Vista -->
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<!-- We were designed and tested on Windows 7 -->
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates application support for Windows Vista -->
<!--supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/-->
</application>
</compatibility>
<!-- Disable file and registry virtualization -->
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>您可以将此文件放在可执行文件的旁边(作为Hyperion.exe.manifest),也可以将其作为RT_MANIFEST资源构建到应用程序中。
注意,我们对称为Microsoft.SQLSERVER.CE.4.0的as程序集有依赖关系。我们首先通过创建一个名为的目录来创建这个程序集:
Microsoft.SQLSERVER.CE.4.0
在部署应用程序时,您将将构成此“程序集”的所有7个dll与一个特殊的Microsoft.SQLSERVER.CE.4.0文件一起放置到此.manifest子文件夹中:
C:\
╰──Users
╰──Ian
╰──AppData
╰──Local
╰──Hyperion Pro
├──Hyperion.exe
├──Hyperion.exe.manifest
╰──Microsoft.SQLSERVER.CE.4.0
├──sqlceme40.dll
├──sqlceca40.dll
├──sqlceoledb40.dll
├──sqlcese40.dll
├──sqlceqp40.dll
├──sqlcecompact40.dll
├──sqlceer40en.dll
╰──Microsoft.SQLSERVER.CE.4.0.manifest换句话说,应用程序文件夹包含应用程序,Microsoft.SQLSERVER.CE.4.0文件夹:
Directory of C:\Users\Ian\AppData\Local\Hyperion Pro
05/29/2012 09:23 AM 1,899,008 Hyperion.exe
05/28/2012 01:46 PM 1,587 Hyperion.exe.manifest
05/29/2012 09:27 AM <DIR> Microsoft.SQLSERVER.CE.4.0
2 File(s) 1,900,675 bytes
1 Dir(s) 20,851,503,104 bytes free任务的下一部分是定义Microsoft.SQLSERVER.CE.4.0.manifest文件。免注册COM允许一个清单文件声明所有COM对象及其clsid,这需要大量的反向工程。但是,4.0的程序集清单是:
Microsoft.SQLSERVER.CE.4.0.manifest
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
type="win32"
name="Microsoft.SQLSERVER.CE.4.0"
processorArchitecture="x86"
version="4.0.0.0" />
<!-- OLEDB Provider -->
<file name = "sqlceoledb40.dll">
<comClass
description = "Microsoft SQL Server Compact OLE DB Provider for Windows"
clsid="{2006C53A-C915-41EA-BAA9-9EAB3A1FBF97}"
threadingModel = "Both"
progid = "Microsoft.SQLSERVER.CE.OLEDB.4.0" />
</file>
<!-- Native flat engine library -->
<file name="sqlceme40.dll" />
<!-- Engine and Replication COM object -->
<file name="sqlceca40.dll">
<comClass description="Active SSCE Engine Object"
clsid="{68D45319-3702-4837-9F8E-DA6845D82482}"
threadingModel="Both"
progid="SSCE.Engine.4.0" />
<comClass description="SSCE Error Object"
clsid="{36228F21-B5C7-4054-8DC2-47D3E236E8B5}"
threadingModel="Both"
progid="SSCE.Error.4.0" />
<comClass description="SSCE Param Object"
clsid="{0B3A7B75-A9B0-4580-9AA5-1A7DA47AD1CB}"
threadingModel="Both"
progid="SSCE.Param.4.0" />
<comClass description="Active SSCE Replication Object"
clsid="{11D5B2D4-26A4-44F5-A48B-0FAC3A919ED8}"
threadingModel="Both"
progid="SSCE.Replication.4.0" />
<comClass description="Active SSCE remote data access Object"
clsid="{58BC9AD6-BF11-40B3-9AB1-E3F2ED784C08}"
threadingModel="Both"
progid="SSCE.RemoteDataAccess.4.0" />
<typelib tlbid="{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}"
version="4.0"
helpdir=""/>
</file>
<comInterfaceExternalProxyStub
name="ISSCEEngine"
iid="{10EC3E45-0870-4D7B-9A2D-F4F81B6B7FA2}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCEError"
iid="{31155A3B-871D-407F-9F73-DEBFAC7EFBE3}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCERDA"
iid="{4F04F79D-1FF1-4DCD-802B-3D51B9356C14}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCEParams"
iid="{A78AFF90-049C-41EC-B1D8-665968AAC4A6}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCEParam"
iid="{A9876C60-2667-44E5-89DB-E9A46ED392C0}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCEErrors"
iid="{C40143CA-E9F9-4FF4-B8B4-CC02C064FC1B}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<comInterfaceExternalProxyStub
name="ISSCEMerge"
iid="{C6EB397F-D585-428D-A4F4-454A1842CB47}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid = "{CE4AACFA-3CFD-4028-B2D9-F272314F07C8}" />
<file name="sqlceqp40.dll" />
<file name="sqlcese40.dll" />
<file name="sqlcecompact40.dll" />
<file name="sqlceer40EN.dll" />
</assembly>最后一个缺点是,我们依赖于一个名为Microsoft.SQLSERVER.CE.4.0的程序集,而4.0又依赖于一个名为Microsoft.VC90.CRT的程序集。幸运的是,SQLCE的安装附带了此程序集的副本:
Microsoft.VC90.CRT
├──Microsoft.VC90.CRT.manifest
╰──msvcr90.dll这意味着最终的目录结构是:
C:\
╰──Users
╰──Ian
╰──AppData
╰──Local
╰──Hyperion Pro
├──Hyperion.exe
├──Hyperion.exe.manifest
╰──Microsoft.SQLSERVER.CE.4.0
├──Microsoft.SQLSERVER.CE.4.0.manifest
├──sqlceme40.dll
├──sqlceca40.dll
├──sqlceoledb40.dll
├──sqlcese40.dll
├──sqlceqp40.dll
├──sqlcecompact40.dll
├──sqlceer40en.dll
╰──Microsoft.VC90.CRT
├──Microsoft.VC90.CRT.manifest
╰──msvcr90.dll发布于 2013-04-06 23:06:00
对于Server 4.0 SP1:
我只是选择将安装文件本身作为EmbeddedResource包含到我的exe中,而不是处理部署中的所有繁琐内容,并执行了以下操作:
public static class RedistHelper
{
private static readonly ILog Log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static readonly string SqlCeRedistName64 = "SSCERuntime_x64-ENU.exe";
private static readonly string SqlCeRedistName32 = "SSCERuntime_x86-ENU.exe";
private static readonly Dictionary<string, Assembly> Assemblies =
new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
private static string SqlCeRedistName
{
get
{
return Environment.Is64BitOperatingSystem
? SqlCeRedistName64
: SqlCeRedistName32;
}
}
public static bool IsSqlCeInstalled()
{
RegistryKey localKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine,
RegistryView.Registry64);
RegistryKey ret = localKey.OpenSubKey(
@"SOFTWARE\Microsoft\Microsoft SQL Server Compact Edition\v4.0\ENU");
return ret != null;
}
private static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, read);
return ms.ToArray();
}
}
public static Assembly OnCurrentDomainOnAssemblyResolve(object sender,
ResolveEventArgs args)
{
Assembly dll;
var name = new AssemblyName(args.Name).Name + ".dll";
if (!Assemblies.TryGetValue(name, out dll))
{
Assembly res = typeof(RedistHelper).Assembly;
using (Stream input =
res.GetManifestResourceStream(typeof(RedistHelper), name))
{
if (input == null)
{
Log.WarnFormat("Assembly {0} does not contain {1}", res, name);
return null;
}
dll = Assembly.Load(ReadFully(input));
if (dll == null)
{
Log.WarnFormat("Assembly {0} failed to load.", name);
return null;
}
Log.InfoFormat("Loaded assembly {0}.", name);
Assemblies[name] = dll;
return dll;
}
}
return dll;
}
public static void InstallSqlCe()
{
using (Stream stream =
typeof(RedistHelper).Assembly.GetManifestResourceStream(
typeof(RedistHelper), SqlCeRedistName))
{
Debug.Assert(stream != null);
byte[] bytes = new byte[(int)stream.Length];
stream.Read(bytes, 0, bytes.Length);
string path = Path.Combine(Path.GetTempPath(), SqlCeRedistName);
if (File.Exists(path))
File.Delete(path);
File.WriteAllBytes(path, bytes);
Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = path,
UseShellExecute = true
}
};
process.Start();
process.WaitForExit();
}
}
}唯一让我头疼的是引用System.Data.SqlServerCe.dll --它根本不需要IlMerge,所以我按需将它加载到我的主目录中:
AppDomain.CurrentDomain.AssemblyResolve += RedistHelper.OnCurrentDomainOnAssemblyResolve;发布于 2019-06-20 18:59:13
不确定是否有什么改变。但是,使用最新的Server包,不再需要应用程序清单。您将得到两组二进制文件: x86和amd64。只需将它们复制到x86和/或amd64子目录下的目标文件夹即可。
|--Your App Dir
|--x86 (x86 sql ce binaries)
|--amd64 (amd64 sql ce binaries)你可以走了。看起来,System.Data.SqlCe.dll可以自动找到并加载本机二进制文件。如果您的应用程序只针对一个平台,也可以在应用程序dir中部署它们。
https://stackoverflow.com/questions/10739845
复制相似问题