locked
compatibilité systèmes RRS feed

  • Question

  • Bonjour,

    En testant VS 2015 RC, je me suis rendu compte qu'un programme généré par ce dernier ne peut fonctionner sous Win7 sans installer une ribambelle de DLL d'ailleurs inconnues et nécessittant l'installation sur le système désirant executer le programme du "redistributable" C++. Cela semble être également le cas pour VS2013

    Ma question est donc double :

    1) En supposant que l'on veuille réaliser un programme qui puisse être lancé à partir d'une clé ou autre (donc portable) et que l'on veuille utiliser une liaison non statique, quelles sont les DLL nécessaires devant être présentes dans la clé pour que celui ci s'execute sur les systèmes windows 64 bits (au moins Win7 à ....Win10). Où peut on trouver ces informations sur le site de microsoft ? Cela me semble aberrant que l'on ne puisse pas le trouver.

    2) Existe t-il une page web quelconque sur le site de microsoft expliquant les différentes manières suivant le système de développement utilisé de cibler tel ou tel système, en particulier la possibilité de garder un programme 32 bits compatible avec Win XP

    En commentaire, je dirais que je ne vois pas trop l'intérêt de développer sur un système qui limite la capacité d'exécuter que sur son propre système et que l'heure est plutôt à rechercher une compatibilité voire même entre différents systèmes d'exploitation et ne comprends pas trop pourquoi cela ne semble pas être la préoccupation de MS au vu des nombreuses recherches infructueuses que j'ai faites sur le net.

    mercredi 8 juillet 2015 08:01

Réponses

  • Bonjour,

    Je vais essayer de faire efficace, quelque soit la version de Visual Studio avec C++, vous avez souvent besoin de livrer les "Redistribuables C++" pour la version de Visual Studio, service pack et achitecture processeur choisie. Autrement dit, vous allez trouver les redistribuables VS 2005 sp1 pour x86 ou x64 (J'ai fait exprès de prendre 2005 pour vous montrer que cela existe depuis bien longtemps. Vous les avez pour 2002, 2005,2008,2010, 2012,2013,2015...:-D).

    Maintenant ne soyez absolument pas surpris par ce comportement, il est tout à fait logique. Lorsque vous faîtes appel à une librairie externe vous avez besoin que cette librairie soit présente sur le système cible, c'est pour cette raison qu'il y a d'ailleurs des setup. Notez que le problème existe également pour .NET, on dépend de la présence d'une version spécifique du Framework, idem pour Java, on dépend d'une version précise de la JRE et du JDK.

    Les choses sont très bien faite (ou du moins mieux faite qu'avant) côté Microsoft pour les dépendances du librairie. Afin de minimiser le "Dll Hell", observez le répertoire C:\WINDOWS\WinSxS. Vous verrez que sur un OS donné, on stocke les librairies et versions nécessaires pour faire tourner les programmes sans risque. Si vous livrez sur une machine déjà équipée des bonnes librairies, tout fonctionne, sinon il n'y a pas d'autre choix que d'installer les dites librairies.

    Peut-on fonctionner autrement ? Assurément. Mais il faut être conscient de ce que l'on fait.

    Tout d'abord avec C++ vous pouvez viser une liaison dynamique ainsi qu'une liaison statique. La version dynamique signifie qu'à l'exécution nous irons chercher des DLL spécifiques. La version statique signifie que les librairies C++ seront directement intégrés dans nos binaires. En faisant ainsi, vous n'avez plus de liaison avec des DLL externes.

    Pourquoi privilégions-nous alors les DLL ? Tout simplement parce que la liaison statique fait grossir inutilement vos binaires. Ils prennent nettement plus de place sur le disque ainsi qu'en mémoire, ne bénéficient pas des fonctionnalités de partage (à l'interne, microsoft fait en sorte qu'une DLL ne soit pas dupliquer en mémoire entre les process sinon on attendrait rapidement les limites), ni des fonctionnalités de mise à jour (un Windows Update ne peut rien faire pour votre programme ainsi buildé, ce qui peut être gênant notamment pou la sécurité).

    Microsoft conseille ainsi la liaison dynamique (https://msdn.microsoft.com/fr-fr/library/vstudio/ms235316(v=vs.110).aspx) mais vous n'êtes pas obligés de la faire si d'autres raisons vous y contraignent.

    Maintenant, pour répondre à votre double question.

    1) Sous Visual Studio, Microsoft effectue par défaut quelques liaisons pour vous, mais vous êtes bien responsables des liaisons de bibliothèque que vous faites. Dans les propriétés de votre projet, dans le linker, Input, vous trouvez dans additionnal dependencies les librairies sur lesquels vous vous branchez (à partir des .lib, vous pourrez déterminer le nom des DLL) à inclure. Autre astuce, vous pouvez lancer le logiciel Depends, il vous montrera les dépendances des DLL (http://www.dependencywalker.com/)... Sans aller aussi loin, en debug sous Visual Studio, vous pouvez voir les modules chargés.

    2) Vaste question car cela dépend des librairies que vous utilisez! Si vous ne prenez que des librairies Microsoft, allez  dans les propriétés de votre programme, C++, Preprocessor, dans les definitions  vous devriez avoir WIN32 ou _WIN32_...

    Concernant votre commentaire, il vous suffirait de coder en .NET. Il y a une dépendance avec le Framework mais c'est beaucoup plus simple. Sinon vous allez  bientôt pouvoir cibler, avec  Windows 10, un .NET Core où tout sera compatible, y-compris Xbox, Windows Phone, etc

    En espérant vous avoir aidé,

    Bien cordialement,

    Fabrice JEAN-FRANCOIS

    mercredi 8 juillet 2015 10:02
  • Non, non, le problème existe bien sur Windows XP... et l'on peut toujours bien bien livrer les dll adéquates pour du Windows 64bits sans passer par de la liaison statique.. Le Side by side (WinSxS) est une solution ultra puissante avec la possibilité d'indiquer via des manifests (qui peuvent être un fichier à part ou bien même intégrés directement dans les binaires) les librairies sur lesquelles on pointe. C'est grâce à cela que l'OS a gagné en stabilité et sécurité.

    Si les librairies ne sont pas présentes dans WinSxS elles sont bien évidemment recherchées dans le local folder, donc vous pouvez bien mettre les DLL nécessaires pour ceux qui ne les possèdent pas ne seraient pas présentes sur la clé. Le fonctionnement est ici logique, si les Dll du WinSxS étant à jour vous aurez les dernières fonctionnalités/corrections de bug. Notez qu'il est possible de demander que le side by side ne soit pas pris en compte (il vous faudra alors bien créer et configurer vos manifests. Cela peut être fastidieux, mais ça fonctionne très bien).

    Si vous n'utiliser pas les MFC, ni autres joyeusetés (j'aime bien ce mot, lol), vos dépendances sont les msvcr(t)<version>, msvcp<version> (cf explication). En revanche ça peut ne pas sembler fonctionner à cause du side by side.

    Bref, lisez bien cet article https://msdn.microsoft.com/en-US/library/ms235342(v=vs.140).aspx ainsi que le suivant https://msdn.microsoft.com/en-US/library/aa374224(v=vs.140).aspx

    Les termes d'Assemblies sont utilisés mais il ne s'agit pas de .NET et bien de DLL pures. L'ensemble est fastidieux à mettre en oeuvre mais quand ça marche c'est nickel.

    mercredi 8 juillet 2015 13:57

Toutes les réponses

  • Bonjour,

    Je vais essayer de faire efficace, quelque soit la version de Visual Studio avec C++, vous avez souvent besoin de livrer les "Redistribuables C++" pour la version de Visual Studio, service pack et achitecture processeur choisie. Autrement dit, vous allez trouver les redistribuables VS 2005 sp1 pour x86 ou x64 (J'ai fait exprès de prendre 2005 pour vous montrer que cela existe depuis bien longtemps. Vous les avez pour 2002, 2005,2008,2010, 2012,2013,2015...:-D).

    Maintenant ne soyez absolument pas surpris par ce comportement, il est tout à fait logique. Lorsque vous faîtes appel à une librairie externe vous avez besoin que cette librairie soit présente sur le système cible, c'est pour cette raison qu'il y a d'ailleurs des setup. Notez que le problème existe également pour .NET, on dépend de la présence d'une version spécifique du Framework, idem pour Java, on dépend d'une version précise de la JRE et du JDK.

    Les choses sont très bien faite (ou du moins mieux faite qu'avant) côté Microsoft pour les dépendances du librairie. Afin de minimiser le "Dll Hell", observez le répertoire C:\WINDOWS\WinSxS. Vous verrez que sur un OS donné, on stocke les librairies et versions nécessaires pour faire tourner les programmes sans risque. Si vous livrez sur une machine déjà équipée des bonnes librairies, tout fonctionne, sinon il n'y a pas d'autre choix que d'installer les dites librairies.

    Peut-on fonctionner autrement ? Assurément. Mais il faut être conscient de ce que l'on fait.

    Tout d'abord avec C++ vous pouvez viser une liaison dynamique ainsi qu'une liaison statique. La version dynamique signifie qu'à l'exécution nous irons chercher des DLL spécifiques. La version statique signifie que les librairies C++ seront directement intégrés dans nos binaires. En faisant ainsi, vous n'avez plus de liaison avec des DLL externes.

    Pourquoi privilégions-nous alors les DLL ? Tout simplement parce que la liaison statique fait grossir inutilement vos binaires. Ils prennent nettement plus de place sur le disque ainsi qu'en mémoire, ne bénéficient pas des fonctionnalités de partage (à l'interne, microsoft fait en sorte qu'une DLL ne soit pas dupliquer en mémoire entre les process sinon on attendrait rapidement les limites), ni des fonctionnalités de mise à jour (un Windows Update ne peut rien faire pour votre programme ainsi buildé, ce qui peut être gênant notamment pou la sécurité).

    Microsoft conseille ainsi la liaison dynamique (https://msdn.microsoft.com/fr-fr/library/vstudio/ms235316(v=vs.110).aspx) mais vous n'êtes pas obligés de la faire si d'autres raisons vous y contraignent.

    Maintenant, pour répondre à votre double question.

    1) Sous Visual Studio, Microsoft effectue par défaut quelques liaisons pour vous, mais vous êtes bien responsables des liaisons de bibliothèque que vous faites. Dans les propriétés de votre projet, dans le linker, Input, vous trouvez dans additionnal dependencies les librairies sur lesquels vous vous branchez (à partir des .lib, vous pourrez déterminer le nom des DLL) à inclure. Autre astuce, vous pouvez lancer le logiciel Depends, il vous montrera les dépendances des DLL (http://www.dependencywalker.com/)... Sans aller aussi loin, en debug sous Visual Studio, vous pouvez voir les modules chargés.

    2) Vaste question car cela dépend des librairies que vous utilisez! Si vous ne prenez que des librairies Microsoft, allez  dans les propriétés de votre programme, C++, Preprocessor, dans les definitions  vous devriez avoir WIN32 ou _WIN32_...

    Concernant votre commentaire, il vous suffirait de coder en .NET. Il y a une dépendance avec le Framework mais c'est beaucoup plus simple. Sinon vous allez  bientôt pouvoir cibler, avec  Windows 10, un .NET Core où tout sera compatible, y-compris Xbox, Windows Phone, etc

    En espérant vous avoir aidé,

    Bien cordialement,

    Fabrice JEAN-FRANCOIS

    mercredi 8 juillet 2015 10:02
  • J'ai fait exprès de prendre 2005 pour vous montrer que cela existe depuis bien longtemps. Vous les avez pour 2002, 2005,2008,2010, 2012,2013,2015...:-D)

    oui mais en 32 bits du moins il suffisait de joindre deux DLL (la runtime C et la biblio C++) et l'on pouvait alors faire tourner le soft sur n'importe quel OS de XP à ...maintenant et donc on pouvait rendre le programme autonome et utilisable par un quidam (n'ayant pas de droit d'administrateur pour installer)

    Notez que le problème existe également pour .NET, on dépend de la présence d'une version spécifique du Framework, idem pour Java, on dépend d'une version précise de la JRE et du JDK.

    c'est bien pour cela que je ne programme pas en .NET en dehors du fait qu'il soit un peu trop exclusivement microsoft et qu'on ai l'impression d'utiliser un marteau pilon pour ecraser une mouche avec .NET (si .NET était dispo sur n'importe quelle machine comme l'est Java et compatible de manière ascendante encore, je ne dis pas ...)

    J'en déduis qu'il n'est plus possible sous Windows 64 bits de distribuer un logiciel simplement qui puisse s'executer sur tout système windows 64 bits même en fournissant quelques DLL, c'est à dire programmer un logiciel en C++ (et uniquement en C++, pas de MFC ni autres joyeusetés du genre), et fournir l'ensemble sur une clé que l'utilisateur branche et lance l'executable pour démarrer en ayant aucun droit administrateur en théorie (impossibilité d'installer quoi que ce soit sur le système). Ai-je raison ?

    mercredi 8 juillet 2015 10:58
  • Non, non, le problème existe bien sur Windows XP... et l'on peut toujours bien bien livrer les dll adéquates pour du Windows 64bits sans passer par de la liaison statique.. Le Side by side (WinSxS) est une solution ultra puissante avec la possibilité d'indiquer via des manifests (qui peuvent être un fichier à part ou bien même intégrés directement dans les binaires) les librairies sur lesquelles on pointe. C'est grâce à cela que l'OS a gagné en stabilité et sécurité.

    Si les librairies ne sont pas présentes dans WinSxS elles sont bien évidemment recherchées dans le local folder, donc vous pouvez bien mettre les DLL nécessaires pour ceux qui ne les possèdent pas ne seraient pas présentes sur la clé. Le fonctionnement est ici logique, si les Dll du WinSxS étant à jour vous aurez les dernières fonctionnalités/corrections de bug. Notez qu'il est possible de demander que le side by side ne soit pas pris en compte (il vous faudra alors bien créer et configurer vos manifests. Cela peut être fastidieux, mais ça fonctionne très bien).

    Si vous n'utiliser pas les MFC, ni autres joyeusetés (j'aime bien ce mot, lol), vos dépendances sont les msvcr(t)<version>, msvcp<version> (cf explication). En revanche ça peut ne pas sembler fonctionner à cause du side by side.

    Bref, lisez bien cet article https://msdn.microsoft.com/en-US/library/ms235342(v=vs.140).aspx ainsi que le suivant https://msdn.microsoft.com/en-US/library/aa374224(v=vs.140).aspx

    Les termes d'Assemblies sont utilisés mais il ne s'agit pas de .NET et bien de DLL pures. L'ensemble est fastidieux à mettre en oeuvre mais quand ça marche c'est nickel.

    mercredi 8 juillet 2015 13:57
  • C'est grâce à cela que l'OS a gagné en stabilité et sécurité.

    Ah bon ? je n'avais pas remarqué (je plaisante)

    Je constate en tous les cas une chose (peut être mon erreur est elle d'essayer de compiler du 64 bits avec win10 et de surcroit VS2015 RC) : par défaut le compilateur m'indique version 8.1 (quesaco ? je connaissais la 5.01 pour XP...etc mais pas la 8.1 et pas d'autres choix), me compile un programme qui pour fonctionner (après avoir scruté avec dependency walker) a besoin de DLL nommées par ex API-WIN-MS-CRT-RUNTIME-L1-1-0.DLL introuvables dans le système autrement que dans un fichier compressé situé "....\packages\vcRuntimeMinimum_amd64\cab1.cab" présent uniquement si on installe le "redistribuable".

    BONJOUR LA TRANSPARENCE !!!

    Et il est donc bien impossible pour un quidam ne pouvant installer le "redistribuable" d'executer un programme ainsi compilé (à moins bien sur de le compiler en statique ce qui présente plein d'inconvénient comme dit précédemment). Est-ce que je me trompe ? ou y at-il une option quelconque permettant de retrouver la compilation avec deux bibliothèques 64 bits msvcr... et msvcp... quelque part ? Je ne crois pas ayant trouvé une msvcp14... mais pas de msvcr14... (semble basé sur VCRUNTIME140.DLL et UCRTBASE.DLL... et toutes les bibliothèques API-..... innombrables et introuvables)

    Bref mes essais ne sont guère satisfaisants pour l'instant

    votre dernière phrase illustre bien ce que je pense de l'évolution de Windows (et pourtant nous serions encore à l'heure des dynosaures informatiques sans Bill) : "quand ça marche c'est nickel" ou "c'est nickel ... quand ça marche"  :)

    mercredi 8 juillet 2015 16:58
  • Le résultat de compilation n'est pas fonction du type d'OS sur lequel VS s'exécute mais est uniquement fonction de comment VS est configuré.

    Si vous n'avez que le choix Win8.1, c'est que vraisemblablement, soit vous n'avez installé que des plateformes SDK compatible Win8.1, soit vous utilisez des options qui ne sont compatible qu'avec cette version de l'OS.

    Si vous voulez des exécutable compatibles avec WinXP, il faut le spécifier dans la configuration de VS (WINVER, ...).

    La Dll "API-WIN-MS-CRT-RUNTIME-L1-1-0.DLL" est livré avec Win8.1, c'est donc normal de s'en servir si c'est la plateforme cible.

    > présent uniquement si on installe le "redistribuable".

    Ce qui est un pré-requis pour tout installation d'un programme généré avec VS, et cela depuis VS1.51 je crois (dans les années 80). C'est pas parce que ça plantait "que" sur les machines vierges, que l'installation n'était pas boguée. C'est juste que travailler comme un sagouin, c'est de plus en plus dur, et travailler selon les normales est de plus en plus simple.

    Pour exécuter un MSI, on n'a pas besoin des droits administrateurs, à moins que le MSI ait été fait à la hache.

    >BONJOUR LA TRANSPARENCE !!!

    C'est pas planqué, et c'est pas une nouveauté.

    >Est-ce que je me trompe ?

    Oui, vous vous trompez, le quidam c'est utiliser un MSI, spécifier des chemins pertinents, le MSI c'est copier les Dll où c'est nécessaire et si vous avez correctement configuré le manifeste de votre application, ça marchera dés la fin de l'installation.

    Vous vous posez plein de questions et de problèmes qui ne se posent pas si vous suivez les préconisations M$ : faire un MSI avec le MSM des redistrubuables associé à la version de la runtime que vous avez configuré dans le projet VS.

    >Bref mes essais ne sont guère satisfaisants pour l'instant

    Vous ramez contre le courant.


    Paul Bacelar, Ex - MVP VC++

    mercredi 8 juillet 2015 18:30
    Modérateur
  • Pour exécuter un MSI, on n'a pas besoin des droits administrateurs

    en partie faux!

    Un article donnant des réponses claires à mon problème :

    http://blogs.msdn.com/b/vcblog/archive/2015/03/03/introducing-the-universal-crt.aspx


    (particulièrement § 6)

    • Marqué comme réponse c.panel samedi 11 juillet 2015 16:05
    • Modifié c.panel samedi 11 juillet 2015 16:41 précision
    • Non marqué comme réponse Paul BacelarModerator lundi 13 juillet 2015 00:51
    samedi 11 juillet 2015 16:04
  • Relisez bien les articles, ils exposent bien la problématique et indique bien que la "solution" que vous propose est bien seule à suivre.


    Paul Bacelar, Ex - MVP VC++

    lundi 13 juillet 2015 00:52
    Modérateur
  • oui, j'ai bien compris : depuis VS2015 et Win10, il n'est plus possible de créer des logiciels portables sous windows sauf à utiliser les outils de VS2013 ou antérieurs ou d'attendre que tous les "anciens" windows (Win7 entre autre) aient tous disparus... triste décision de microsoft mais qui a le mérite ici dans cet article d'être clairement annoncée.
    lundi 13 juillet 2015 08:38
  • WHAT ???

    Vous devez lire en diagonal, et sur la mauvais, (celle du fou ?).

    Ils ont juste isolés la partie non compilateur dépendante de la C-Runtime dans un module fourni avec l'OS ou via Windows Update, comme Kernel32.dll.

    C'est quasi l'opposé de ce que vous dite, mais sur un périmètre beaucoup plus restreint.

    J'ai l'impression de dialoguer avec un troll-bot là.


    Paul Bacelar, Ex - MVP VC++

    lundi 13 juillet 2015 17:47
    Modérateur