Как развернуть SQL Server Compact Edition 4.0?

Как развернуть Microsoft SQL Server Compact 4.0 ?


SQL Server Compact Edition (в настоящее время версии 4.0):

бесплатную встроенную базу данных, которую разработчики программного обеспечения могут использовать для создания настольных приложений Windows. Он имеет небольшую площадь и поддерживает частное развертывание своих двоичных файлов в папке приложения.

Но как вы его развертываете?

  • Microsoft заявляет, что она может быть развернута в папке приложения ( хорошо ) и поддерживает развертывание xcopy .
  • Microsoft также заявляет, что не может быть развернута в папке приложения ( плохая ) и не поддерживает развертывание xcopy .
  • некоторые люди имеют примеры этого, используя простое развертывание xcopy , но они не вникают в детали, необходимые для завершения развертывания

Проблема в том, что вы не можете использовать поставщик ADO OLEdb, если он не зарегистрирован. Регистрация поставщика OLEdb должна выполняться как администратор. Это означает, что версия SQL Server Compact будет терпеть неудачу с пользователями, которые не являются администраторами.

SQL Server Compact 4.0 поставляется с файлом redist_enu.txt :

Перечисленные .exe-файлы устанавливают прилагаемые компоненты в определенное место на конечном компьютере. Это помогает обеспечить исправность и техническую поддержку. Файлы .dll, заключенные в эти .exe-файлы, также доступны отдельно в этом файле redist.txt. Однако распределение этих отдельных DLL может привести к проблемам работоспособности. Для получения дополнительной информации см. Http://go.microsoft.com/fwlink/?LinkId=94589

Частное развертывание с помощью BreadCrumb: частное развертывание только собственного стека и явная загрузка сборки SQL Server Compact через Assembly.LoadFrom (), .local файл или использование страtagsй перенаправления DLL / COM не поддерживаются и могут привести к проблемам с техникой обслуживания , Для получения дополнительной информации см. Http://support.microsoft.com/kb/835322 и http://msdn2.microsoft.com/en-us/library/aa375142.aspx

Microsoft SQL Server Compact 4.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

но он не дает никакой информации о том, как перераспределять SQL Server Compact 4.0.

Случайно spellunking вокруг недокументированной папки Program Files я нашел 7 dlls:

 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 Connection с помощью строки подключения :

 Provider=Microsoft.SQLSERVER.CE.OLEDB.4.0;Data Source="store.sdf" 

но с ошибкой 0x80004005 Unspecified error

Я попробовал frobbing виджета, но он наткнулся на frobber.

2 Solutions collect form web for “Как развернуть SQL Server Compact Edition 4.0?”

Я создал решение.

SQL Server Compact Edition состоит из 7 библиотек dll:

  • sqlceme40.dll Недокументированная, собственная, плоская библиотека API (assembly .net System.Data.SqlServerCe.dll является оберткой вокруг этой DLL)
  • sqlceca40.dll COM-библиотека COM, которая реализует Engine , Replication , Error и несколько других COM-объектов
  • sqlceoledb40.dll COM-библиотека COM, которая реализует поставщик OLEdb для SSCE (разрешая использование ADO)
  • sqlcese40.dll неизвестно
  • sqlceqp40.dll неизвестно
  • sqlcecompact40.dll неизвестно
  • sqlceer40en.dll неизвестно

Проблема с попыткой просто отправить эти DLL состоит в том, что два из них являются COM- объектами. COM-объект dll необходимо зарегистрировать , например:

 >regsvr32 sqlceca40.dll >regsvr32 sqlceoledb40.dll 

Проблема в том, что для регистрации COM-объекта требуются административные привилегии ( с использованием глобального решения для решения локальной проблемы ). Это означает, что ваши пользователи

  • необходимо установить приложение (которое вы не хотите делать)
  • требует, чтобы у ваших пользователей были административные разрешения (которые вы не хотите делать)

К счастью, начиная с 2001 года в Windows XP, Microsoft решила эту проблему с COMmon: Registration-Free COM .

Во-первых, вы заявите, что ваше приложение имеет «зависимость» от SQL Server Compact Edition 4.0. Вы делаете это, создавая манифест собрания:

 < ?xml version="1.0" encoding="UTF-8" standalone="yes"?>   Hyperion Pro       
     true                     

Вы можете поместить этот файл рядом с вашим исполняемым файлом (например, Hyperion.exe.manifest ), или вы можете создать его в своем приложении в качестве ресурса RT_MANIFEST .

Обратите внимание, что мы имеем зависимость от сборки под названием Microsoft.SQLSERVER.CE.4.0 . Сначала мы создаем эту сборку, создавая каталог с именем:

Microsoft.SQLSERVER.CE.4.0

При развертывании приложения вы разместите все 7 библиотек dll, которые include эту «сборку» в эту подпапку 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  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’s. Это заняло много обратной инженерии. Но манифест сборки для SQL Server Compact Edition 4.0:

Microsoft.SQLSERVER.CE.4.0.manifest :

 < ?xml version="1.0" encoding="UTF-8" standalone="yes"?>                              

Окончательный результат заключается в том, что так же мы имеем зависимость от сборки под названием Microsoft.SQLSERVER.CE.4.0 , SQL Server Compact Edition 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 

Для Sql Server Ce 4.0 SP1:

Вместо того, чтобы решать все сложные задачи развертывания, я просто решил включить файлы настроек в мой exe как EmbeddedResource и сделал этот маленький помощник:

  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 Assemblies = new Dictionary(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; 
Давайте будем гением компьютера.