2010-01-25 6 views
6

Hmmm. Ok après avoir revu PInvoke, je suis sûr que je ne comprends pas tout à fait: -/(juste demandé this question)Référencement shell32 à nouveau, C# Visual Studio

Laissez-moi illustrer le code que j'ai besoin de gérer. Cela fonctionne quand j'utilise "Ajouter une référence -> COM -> contrôles Microsoft Shell et Automatation" ... mais malheureusement, il place une référence dans mon projet qui ressemble à ceci: "C: \ Users \ Tim \ Documents \ Visual Studio 2008 \ Projects \ Wing \ FileWing \ obj \ Debug \ Interop.Shell32.dll "

Je suis en train de creuser dans le bac de recyclage et je cherche un objet que je veux récupérer. Y a-t-il un moyen de NE PAS se battre à travers le PInvoke pour y arriver? Ou pour obtenir une référence à system32/shell32.dll qui me permet d'utiliser ce code lors de l'exécution?

private void recoverRecyclerBinEntry(string fileName, int size) 
{ 
    try 
    { 
     Shell Shl = new Shell(); 
     Folder Recycler = Shl.NameSpace(10); 

     // scans through all the recyclers entries till the one to recover has been found 
     for (int i = 0; i < Recycler.Items().Count; i++) 
     { 
      FolderItem FI = Recycler.Items().Item(i); 
      string FileName = Recycler.GetDetailsOf(FI, 0); 
      if (Path.GetExtension(FileName) == "") 
       FileName += Path.GetExtension(FI.Path); 
      //Necessary for systems with hidden file extensions. 

      string FilePath = Recycler.GetDetailsOf(FI, 1); 
      string combinedPath = Path.Combine(FilePath, FileName); 

      if (size == FI.Size && fileName == combinedPath) 
      { 
       Debug.Write("Match found. Restoring " + combinedPath + "..."); 
       Undelete(FI); 
       Debug.WriteLine("done."); 
      } 
      else 
      { 
       Debug.WriteLine("No match"); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine(ex.Message); 
     Debug.WriteLine(ex.StackTrace); 
    } 
} 

private bool Undelete(FolderItem Item) 
{ 
    try 
    { 
     foreach (FolderItemVerb FIVerb in Item.Verbs()) 
     { 
      if (
       (FIVerb.Name.ToUpper().Contains("WIEDERHERSTELLEN")) || 
       (FIVerb.Name.ToUpper().Contains("ESTORE")) || 
       (FIVerb.Name.ToUpper().Contains("NDELETE")) 
       ) 
      { 
       FIVerb.DoIt(); 
       return true; 
      } 
     } 
     //execute the first one: 
     Item.Verbs().Item(0).DoIt(); 
     return true; 
    } 
    catch (Exception) 
    { 
     Debug.WriteLine("ERROR undeleting"); 
     return false; 
    } 
} 

Répondre

7

En ce moment vous mélangez 2 concepts différents: PInvoke et COM Interop. PInvoke vous permet d'accéder aux fonctions C natives à partir du code managé. Il fonctionne en définissant une signature compatible marshal de la méthode native dans le code managé et en la marquant avec l'attribut DllImport. Il nécessite, et ne peut pas avoir, une référence de métadonnées à la DLL native. La DLL est découverte au moment de l'exécution en utilisant des règles de chargement normales pour une DLL Win32. COM Interop vous permet d'accéder aux objets compatibles COM à partir du code managé. Cela se fait en obtenant une définition gérée compatible marshal de l'interface COM, puis en obtenant une référence à l'objet de plusieurs façons. L'obtention de la définition gérée est souvent effectuée au moyen de l'ajout d'une référence de métadonnées à l'assembly PIA (assembly d'interopérabilité principal) pour le composant COM. Jusqu'à C# 4.0, cette référence ne peut pas être supprimée, sans beaucoup de travail, et doit être déployée avec votre application.

Dans cet exemple particulier, vous utilisez COM interop et non PInvoke.

+0

Tout d'abord - désolé, juste fini l'université et ils n'enseignent pas les winapis là ;-) Ok, donc j'utilise COM interop. Vous dites que j'ai besoin d'une référence à l'assembly Interop. Je suppose que c'est ce truc ici, qui est plutôt petit et ok pour moi: .. \ Visual Studio 2008 \ Projets \ Wing \ FileWing \ obj \ Debug \ Interop.Shell32.dll Maintenant ma question est: comment puis-je influencer où cet objet est créé (comme définir le chemin de cet objet ailleurs) ou comment puis-je déployer cet objet avant, de sorte qu'il est installé avec mon application? – Akku

+0

@Tim, je ne crois pas que vous pouvez influencer où il est créé. C'est fait automatiquement par le système de construction. Pour le déployer, copiez-le simplement dans le dossier de destination de votre application. – JaredPar

+0

Merci! C'est exactement ce que je devais faire :-) – Akku