Partage
  • Partager sur Facebook
  • Partager sur Twitter

C# object COM vers interface Shell32

Erreur

Sujet résolu
    18 octobre 2021 à 10:11:35

    Bonjour, déjà merci à tous de lire ce message.

    J'ai modifié mon post par du code... donc je re-edit

    J'ai un problème sur mon logiciel il m'indique cette erreur :

    "
    Impossible d'effectuer un cast d'un object COM de type 'System._ComObject' en type d'interface 'Shell32.Shell'. Cette opération a échoué, car l'appel QueryInterface sur le composant COM pour l'interface avec l'IID XXXX a échoué en raison de l'erreur suivante: Cette interface n'est pas prise en charge.
    "

    Il y a beaucoup de post sur ce sujet et peu de solution, donc je me permet de solliciter l'aider de la commu OC

    Voici un bout de code:

                string getShortCut(string PathLnk)
                {
                    string pathOnly = Path.GetDirectoryName(PathLnk);
                    string filenameOnly = Path.GetFileName(PathLnk);
    
                    Shell shell = new Shell();
                    Folder folder = shell.NameSpace(pathOnly);
                    FolderItem folderItem = folder.ParseName(filenameOnly);
                    MessageBox.Show("" + folderItem);
                    if (folderItem != null)
                    {
                        ShellLinkObject link = (ShellLinkObject)folderItem.GetLink;
    
                        return link.Path;
                    }
                    return ""; // not found
                }

    Le message apparaît à cause de la ligne 6
    Mauvaise utilisation ? Dll manquante que je dois mettre manuellement ?

    Ce code récupère un fichier . lnk (un raccourcis) pour nous donner le chemin cible

    Exemple: Desktop/vers_mes_fichiers_privés.lnk => Document/Perso/MonDossierPrives/MesFichiers

    PS: l’exécutable fonctionne bien sur mon pc (windows 10) celui où j'ai coder mais ne fonctionne pas sur les autres pc.
    J'indique également que je suis en c# .net forms

    PS2: Sur l'autre pc sur lequel il ne fonctionnait pas, je l'ai lancé via visual studio 2019 et il fonctionne. Mais l’exécutable toujours pas

    Merci pour toute aide :)


    -
    Edité par 172-PetitDev 18 octobre 2021 à 10:36:40

    • Partager sur Facebook
    • Partager sur Twitter
      18 octobre 2021 à 11:07:46

      Je suis assez étonné que mes recherches très très rapide sur Google ne m'ait pas données de composant "full" .NET pour ce type de fonctionnalité.

      C'est un domaine extrêmement sensible d'un point de vue sécurité, donc ceci peut expliquer cela.

      Ce que vous avez comme erreur est une erreur "bateau" en COM, qui correspond à quelque-chose de très précis au niveau de la mécanique COM.

      Mais si vous n'avez aucune notion de COM (qui est une technologie "très" vieille, comme moi), cela paraîtra comme du Chinois (à un non Cynophile, maintenant que le Mandarin n'est plus si exotique, je me fais vieux, très vieux).

      La différence de comportement en fonction de la machine et de la manière dont s'est lancé (ainsi que par qui c'est lancé), c'est un peu la plaie de cette technologie COM.

      Si vous pouvez faire sans, faites le.

      Il y a pas mal de moyens pour savoir précisément ce qui cloche mais faut déjà un peu connaitre COM pour ne pas être perdu.

      Je vais donc faire une supputation qui colle avec votre description et qui est assez probable.

      Vous devez être "admin" de votre poste de développement mais le compte utilisé sur l'autre machine ne l'ai vraisemblablement pas.

      Il est assez courant que l'on lance VS en administrateur, ce qui permet de régler le "problème".

      Vous êtes sûr que le compte utilisé sur la machine de test a les droits aussi bien sur le "fichier" de lien que sur la cible ?

      L'EventLog est notre ami.

      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        18 octobre 2021 à 11:12:25

        Bonjour bacelar,

        J'ai effectivement aucune notion sur COM.
        J'aimerai faire sans cependant je ne vois pas comment, j'essaye de chercher pour récupérer les "cibles" des fichiers . lnk mais sans franc succès autre par com Shell

        Oui, mon autre pc est également administrateur et le soft ouvert en administrateur également

        Je me renseigne pour savoir si je peux faire autrement

        Merci pour le message
        Une autre idée de cette petite erreur ?

        -
        Edité par 172-PetitDev 18 octobre 2021 à 11:12:45

        • Partager sur Facebook
        • Partager sur Twitter
          18 octobre 2021 à 12:57:46

          Etre administrateur ne fournit pas tous les droits mais permet de se donner tous les droits, c'est une différence assez subtile.

          Vérifiez que vous ayez encore des outils COM dans votre Visual Studio.

          Avec ceux-ci, vous devriez avoir plus d'information sur le pourquoi du comment.

          Quel est l'UUID de l'objet qui est retourné quand votre instanciation de "Shell" renvoie une erreur lors du QueryInterface ?

          Avec les outils, essayez de lister l'ensemble des Interfaces supportées par l'objet "Shell".

          • Partager sur Facebook
          • Partager sur Twitter
          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
            18 octobre 2021 à 14:17:04

            IID: 286E6F1B-7113-4355-9562-96B7E9D64C54
            HRESULT: 0x80004002 (E_NOITERFACE)

            Oui, j'ai tous les outils COM comme mentionner tout fonctionne bien quand je le lance via Visual Studio mais pas quand je le lance sans Visual Studio

            ça serait possible simplement qu'il retrouve pas sa dll shell ? 'Interop.Shell32.dll'

            Je n'ai pas compris la demande:
            "
            Avec les outils, essayez de lister l'ensemble des Interfaces supportées par l'objet "Shell".
            "
            Je peux voir ça où ? Cependant j'ai vu également que sur un autre windows 10 je n'obtient pas cette erreur, sur l'autre ordinateur que j'essayais était un windows 7, ça n'aurait pas un rapport avec "powershell" sauf si je me trompe ?

            Windows 10 Dev : Fonctionne avec et sans visual studio
            Windows 7 : Fonctionne avec visual studio
            Windows 10 : à l'air de fonctionner
            • Partager sur Facebook
            • Partager sur Twitter
              18 octobre 2021 à 16:07:57

              Une recherche avec l'IID montre que ce composant comme n'est pas "Free Apartment Threaded" et qu'il demande un contexte STA :

              https://stackoverflow.com/questions/31403956/exception-when-using-shell32-to-get-file-extended-properties

              Mais bon, ça serait pas très cohérent avec votre comportement avec et sans VS.

              Et faire du MTA sous WinForms, généralement on est au courant. (Vous faites du multi-threading ?)

              L'une des 3 réponses utilise une approche beaucoup plus directe, donc plus simple à décortiquer et comprendre (la réponse de Maarten Kieft).

              >ça serait possible simplement qu'il retrouve pas sa dll shell ? 'Interop.Shell32.dll'

              Peu probable, normalement, le message d'erreur serait bien différent.

              Utilisez un outil comme process monitor ( https://docs.microsoft.com/en-us/sysinternals/downloads/procmon ) pour en être sûr. (Ou avec votre Process Explorer/Gestionnaire des tâches, si votre OS est assez récent je crois, et que vous pouvez l'intercepter avant fermeture définitive.)

              Que le comportement change en fonction de l'OS, de son niveau de Service Pack, ou des outils de développement installés, ça ne m'étonne pas car le composant COM "Shell" a toujours été une horreur de configuration (de sécurité) car il est extrêmement sensible au niveau sécurité.

              Donc oui, comme l'installation d'outil comme PowerShell ou VS ne se prive pas de changer la configuration de sécurité (généralement pour "l'assouplir"), ça peut changer le composant logiciel que vous récupérez ainsi que les droits qui y sont associé).

              Le fait que vous passiez par VS pour lancer les outils COM peut facilement changer leur comportement : changement de compte utilisateur, changement de statut administrateur, changement des variables d’environnement, changement des droits réclamés, etc...

              Utilisez ces outils plutôt à l'extérieur de VS pour être plus proche de l’environnement de votre programme en "stand alone". Ces exécutables n'ont normalement pas besoin de VS pour tourner, vous pouvez normalement juste copier l'exécutable sur la machine de test.

              >>Avec les outils, essayez de lister l'ensemble des Interfaces supportées par l'objet "Shell".

              Je me rappelle plus trop mais je pense que des outils comme "COM Object Explorer" doivent fournir cette information.

              L'EventLog est notre ami. (BIS)

              Et RegEdit aussi.

              • Partager sur Facebook
              • Partager sur Twitter
              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                19 octobre 2021 à 11:28:26

                Bonjour bacelar,

                Le STAThread était déjà actif et ne change pas la donne

                La solution sur le forum, je n'ai soit pas compris comment l'utiliser ou ce n'est pas la bonne solution dans mon cas

                Je regarde ça avec COM Object Explorer

                EDIT: vous connaissez un autre moyen pour avoir la "cible" d'un fichier lnk ?

                Cordialement



                RE-EDIT:

                J'ai réussi !

                Bon, je suis passé par une autre solution et j'aimerai comprendre quand même pourquoi ça ne fonctionnait pas.

                Mais voici la solution que j'ai utilisé

                Fonctionne sur tous les os de 7 à 10 autres pas essayé

                Référence : C:\Windows\system32\wshom.ocx

                Using : using IWshRuntimeLibrary;

                Function :
                public static string GetShortcutTarget(string lnkFile)
                {
                if (System.IO.File.Exists(lnkFile))
                 {
                 WshShell shell = new WshShell();
                 IWshShortcut link = (IWshShortcut)shell.CreateShortcut(lnkFile);
                 string targetpath = link.TargetPath;
                 return targetpath;
                 }
                return string.Empty;
                }


                Merci à Bacelar pour m'avoir aidé

                Cordialement

                -
                Edité par 172-PetitDev 19 octobre 2021 à 12:09:01

                • Partager sur Facebook
                • Partager sur Twitter
                  19 octobre 2021 à 14:52:10

                  GG !!!

                  Un .ocx, c'est exactement comme un .dll.

                  Sauf qu'on indique par-là que le fichier contient le code exécutable d'un ou plusieurs composants COM.

                  Ils (M$) n'ont malheureusement pas fait cela avec les assemblies .NET qui se cachent dans des .dll sans qu'on puisse savoir si c'est un assembly .NET où une Dll "standard" sans l'ouvrir dans des outils spécialisés.

                  Vous n'indiquez pas comment vous ajoutez la référence qui vous permet d'avoir le type "Shell" dans votre 1er code, je ne peux pas être précis sur les mécanismes en jeu mais je suppute que vous avez dû utiliser des références à un wrapper .NET. Il doit vraisemblablement wrapper un autre composant COM, ou utiliser la configuration enregistrée dans la base de registre pour déterminer dynamiquement quel conteneur de composant utiliser, ou encore utiliser les composants dans "wshom.ocx" mais dans un autre contexte de sécurité (modèle de sécurité CAS, etc...).

                  Si vous avez référencé directement l'ocx, le compilateur a généré automatiquement des wrappers .NET "autour" des composants COM publiés par l'ocx. (couche d'interopérabilité .NET-COM)

                  "wshom" c'est pour "Microsoft Windows Script Host Runtime Library by Microsoft" et de mon temps (il y a plus de 20 ans), il contenait rien pour accéder aux fichiers et on devait passer par des composants enregistrées dans la base de registre (vraisemblablement comme votre premier code) et c'était la fête à la saucisse : ça marche ici mais pas là parce que machin est installé après bidule, etc... (vous connaissez la chanson :lol:).

                  Ils ont dû intégrer ces fonctionnalités directement dans "wshom" ou fiabiliser le machin pour utiliser "facilement" les autres composants COM.

                  Mais je ne suis pas sûr que cette manière de faire soit "officielle", il se peut que cet OCX disparaissent dans le futur.

                  Attention, là où vous l'avez chopé, c'est du 32bits donc faite en sorte que votre exécutable ne s'exécute qu'en 32bits.

                  Je vous conseille aussi de bien analyser les versions/historique de ce composant et dans choisir une version correspondant à votre/vos plateforme cibles et dans faire un composant installable/updatable dans votre solution de déploiement.

                  Courage ;-)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                    19 octobre 2021 à 16:28:06

                    Merci pour toute l'explication,

                    J'ai ajouté Sheel32.dll via visual studio -> clique droit -> ajouter une réference -> parcourir -> system32/sheel32.dll

                    En tous cas merci pour tous ;)
                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 octobre 2021 à 17:13:23

                      Ok, c'est aussi une méthode un peu "directe", sans prise en compte de la base de registre (si c'est un container de composant COM), ou du GAC (si c'est un assembly .NET), etc...

                      Vraisemblablement le "composant" dans Sheel32.dll (Y a pas une typo dans le nom ?) est plus à cheval sur la sécurité que wshom.ocx.

                      C'est aussi un composant 32bits only donc même problème de déploiement potentiel.

                      Vous pouvez vérifier que le problème n’apparaît pas uniquement quand vous essayez de charger ce composant dans un processus 64bits ?

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                      C# object COM vers interface Shell32

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      • Editeur
                      • Markdown