47 votes

Comment déployer SQL Server Compact Edition 4.0 ?

Comment puis-je déployer Microsoft SQL Server Compact 4.0 ?


SQL Server Compact Edition (actuellement à la version 4.0) est :

une base de données gratuite et intégrée que les développeurs de logiciels peuvent utiliser pour créer des applications de bureau Windows. Elle a un faible encombrement et prend en charge le déploiement privé de ses binaires dans le dossier de l'application.

Mais comment le déployer concrètement ?

Le problème est que vous ne pouvez pas utiliser le fournisseur ADO OLEdb à moins qu'il ne soit enregistré. L'enregistrement d'un fournisseur OLEdb doit être effectué en tant qu'administrateur. Cela signifie que l'édition Compact de SQL Server échouera avec les utilisateurs qui ne sont pas des administrateurs.

SQL Server Compact 4.0 est livré avec un redist_enu.txt archivo:

Les fichiers .exe répertoriés installent chacun les composants qu'ils contiennent à un emplacement spécifique de l'ordinateur de destination. Cela permet de garantir la facilité d'entretien et l'assistance technique. Les fichiers .dll inclus dans ces fichiers .exe sont également disponibles séparément dans ce redist.txt. Cependant, la distribution de ces fichiers .dll séparés peut entraîner des problèmes de fonctionnement. Pour plus de détails, veuillez consulter http://go.microsoft.com/fwlink/?LinkId=94589

Détection du déploiement privé via BreadCrumb : Le déploiement privé de la pile native uniquement et le chargement explicite de SQL Server Compact Assembly via Assembly.LoadFrom(), le fichier .local ou l'utilisation de stratégies de redirection DLL/COM ne sont pas pris en charge et peuvent entraîner des problèmes de fonctionnement. Pour plus d'informations, voir http://support.microsoft.com/kb/835322 y 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

mais il ne donne aucune information sur la façon de redistribuer SQL Server Compact 4.0.

L'épellation aléatoire des sans-papiers Program Files j'ai trouvé 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

Note : Il y a aussi des dossiers enfants avec plus de dlls.

J'ai essayé de copier ces 7 dll dans un dossier, et j'ai essayé d'ouvrir un fichier de type Connexion ADO en utilisant la chaîne de connexion :

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

mais il échoue avec 0x80004005 Unspecified error

J'ai essayé de frober le widget, mais il a frobbé le frobber.

0 votes

Je ne l'ai jamais fait moi-même, mais la documentation n'est-elle pas claire ? msdn.microsoft.com/fr/us/library/aa983326(v=vs.110).aspx

1 votes

Voir mon billet de blog ici : erikej.blogspot.com/2011/02/ Utilisation de SQL Server Compact 4.0 avec Desktop Private Deployment et un projet Setup (MSI) (partie 2)

0 votes

Vous faites référence app.config Je suis en train d'utiliser une application native avec un déploiement xcopy.

52voto

Ian Boyd Points 50743

J'ai créé la solution.

SQL Server Compact Edition est composé de 7 dlls :

  • sqlceme40.dll La bibliothèque API plate, native et non documentée (The .net System.Data.SqlServerCe.dll est une enveloppe autour de cette dll)
  • sqlceca40.dll Une dll COM qui implémente Engine , Replication , Error et quelques autres objets COM
  • sqlceoledb40.dll Une dll COM qui implémente un fournisseur OLEdb pour SSCE (permettant l'utilisation de ADO).
  • sqlcese40.dll inconnu
  • sqlceqp40.dll inconnu
  • sqlcecompact40.dll inconnu
  • sqlceer40en.dll inconnu

Le problème quand on essaie d'expédier simplement ces fichiers DLL est que deux d'entre eux sont COM objets. Les dll d'objets COM doivent être enregistré par exemple :

>regsvr32 sqlceca40.dll
>regsvr32 sqlceoledb40.dll

Le problème est que l'enregistrement d'un objet COM requiert administratif les privilèges ( utiliser une solution globale pour résoudre un problème local ). Cela signifie que vos utilisateurs

  • doivent installer votre application (ce que vous ne voulez pas faire)
  • exige que vos utilisateurs aient des droits d'administration (ce que vous ne voulez pas faire)

Heureusement, à partir de 2001 avec Windows XP, Microsoft a résolu ce problème de COMmon : COM sans inscription .

Tout d'abord, vous déclarerez que votre application a une "dépendance" sur SQL Server Compact Edition 4.0. Pour ce faire, vous devez créer un manifeste d'assemblage :

<?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>

Vous pouvez placer ce fichier à côté de votre exécutable (en tant que Hyperion.exe.manifest ), ou vous pouvez l'intégrer dans votre application en tant que RT_MANIFEST ressource.

Remarquez que nous avons une dépendance par rapport à un assemblage appelé Microsoft.SQLSERVER.CE.4.0 . Nous créons d'abord cet assemblage en créant un répertoire appelé :

Microsoft.SQLSERVER.CE.4.0

Lorsque vous déployez votre application, vous placez les 7 dll qui la composent dans votre système. "assemblage" dans ce Microsoft.SQLSERVER.CE.4.0 ainsi qu'un sous-dossier spécial .manifest archivo:

0 votes

Mon Dieu, quel voyage autour de la grange de Robin des Bois. Il y a un chemin beaucoup plus simple : déploiement privé . Vous pouvez aller un peu plus loin en ne copiant même pas les assemblages privés et les fichiers VC++ dans votre projet - il suffit de créer un lien vers eux et de définir l'action de construction sur Copier si c'est nouveau.

0 votes

@InteXX Tout cela nécessite, et suppose, Visual Studio. Il existe d'autres IDE qui construisent des exécutables Win32/64 natifs.

1 votes

Oui, vous avez raison. Cette procédure particulière de déploiement privé ne fonctionne qu'avec Visual Studio. Les autres auront besoin d'un autre moyen. C'est un bon article sur le COM sans enregistrement. Je m'y référerai la prochaine fois que j'aurai à le faire. Bon travail.

8voto

Pour Sql Server Ce 4.0 SP1 :

Au lieu de m'attaquer à tous les détails du déploiement, j'ai simplement choisi d'inclure les fichiers d'installation eux-mêmes dans mon exe comme EmbeddedResource et j'ai fait cette petite aide :

 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();
            }
        }
    }

La seule chose qui m'a vraiment donné un mal de tête était de référencer la dll System.Data.SqlServerCe.dll - elle ne voulait tout simplement pas IlMerge, donc à la place je l'ai chargée à la demande, dans ma main :

AppDomain.CurrentDomain.AssemblyResolve += RedistHelper.OnCurrentDomainOnAssemblyResolve;

1voto

Shao Skywalker Points 21

Je ne sais pas si quelque chose a changé ou pas. Mais avec le dernier paquet nuget de SQL Server CE, les manifestes d'application ne sont plus nécessaires. Vous obtiendrez deux ensembles de binaires : x86, et amd64. Copiez-les simplement dans votre dossier cible sous le sous-répertoire x86 et/ou amd64.

|--Your App Dir
   |--x86 (x86 sql ce binaries)
   |--amd64 (amd64 sql ce binaries)

Et vous êtes prêt à partir. On dirait que la dll System.Data.SqlCe.dll peut trouver et charger automatiquement les binaires natifs. Vous pouvez également les déployer dans le répertoire de l'application si votre application n'est destinée qu'à une seule plateforme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X