web-dev-qa-db-fra.com

GetManifestResourceStream renvoie NULL

Ceci est une application C # .NET 4.0:

J'incorpore un fichier texte en tant que ressource, puis j'essaie de l'afficher dans une boîte de dialogue:

    var Assembly = Assembly.GetExecutingAssembly();
    var resourceName = "MyProj.Help.txt";

        using (Stream stream = Assembly.GetManifestResourceStream(resourceName))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                string result = reader.ReadToEnd();
                System.Windows.Forms.MessageBox.Show(result, "MyProj", MessageBoxButtons.OK);
            }
        }

La solution est MyProjSolution et l'exécutable est MyProj.exe. Help.txt est une ressource intégrée. Cependant, le flux est nul. J'ai essayé MyProjSolution.Help.txt et MyProjSolution.MyProj.Help.txt mais rien ne semble fonctionner.

58
Ron

Vous pouvez vérifier que les ressources sont correctement intégrées en utilisant 

//From the Assembly where this code lives!
this.GetType().Assembly.GetManifestResourceNames()

//or from the entry point to the application - there is a difference!
Assembly.GetExecutingAssembly().GetManifestResourceNames()

lors du débogage. Ceci listera tous les (noms qualifiés complets) de toutes les ressources incorporées dans l’Assemblée dans laquelle votre code est écrit.

Voir Assembly.GetManifestResourceNames () sur MSDN.

Copiez simplement le nom approprié et utilisez-le à la place de ce que vous avez défini dans la variable 'nom_ressource'. 

Remarques - le nom de la ressource est sensible à la casse et si vous avez incorporé le fichier de ressource de manière incorrecte, il n'apparaîtra pas dans la liste renvoyée par l'appel de GetManifestResourceNames (). De plus, assurez-vous de lire la ressource à partir du bon assemblage (si plusieurs assemblys sont utilisés), il est très facile d'obtenir les ressources de l'assembly en cours d'exécution plutôt que d'un assemblage référencé.

EDIT - .NET Core
Veuillez voir ceci SO post pour plus de détails sur l’incorporation à l’aide de .NET Core. 

La récupération des informations sur le manifeste semble être similaire - utilisez simplement this.GetType().GetTypeInfo().Assembly.GetManifestResourceNames() pour obtenir un manifeste à partir de l'assembly où le code est en cours d'exécution.

Je n'ai pas encore compris comment faire l'équivalent de Assembly.GetExecutingAssembly() dans .NET Core! si quelqu'un le sait - faites-le moi savoir et je mettrai à jour cette réponse.

130
Jay

Un problème similaire s’est d'abord posé pour vérifier que le fichier est inclus dans votre projet, puis aller dans propriétés et définir l'action de génération de ce fichier sur Embedded Resource. cela a fonctionné pour moi. 

43
Jithesh Chandra

Juste un avertissement. 

Je ne pouvais pas accéder à mon fichier en tant que ressource incorporée même si je l'avais spécifié et qu'il possédait cette propriété Action de construction. J'ai perdu beaucoup de temps à me cogner la tête. J'ai incorporé un fichier de code csharp avec l'extension .txt à son nom (xxx.cs.txt). Pour une raison quelconque, les méthodes GetManifestResourceNames () et GetManifestResourceStream () ne verront pas un fichier contenant le nom .cs.

Je l'ai renommé simplement xxx.txt et tout allait bien.

Bizarre.

6
Belmiris

Voici la cause de ma valeur nulle.

http://adrianmejia.com/blog/2011/07/18/cs-getmanifestresourcestream-gotcha/

La méthode GetManifestResourceStream renvoie toujours NULL si la propriété de la ressource "action construite" n'est pas définie sur "ressource incorporée".

Après avoir défini cette propriété avec tous les fichiers nécessaires, Assembly.GetManifestResourceStream commence à renvoyer le flux actuel au lieu de NULL.

6
Nate

La propriété "Action de construction" du fichier incorporé doit être définie comme suit: "Ressource incorporée" pour exécuter correctement la ligne ci-dessous:

Stream stream = Assembly.GetManifestResourceStream(resourceName)

Cliquez avec le bouton droit sur le fichier, cliquez sur la propriété, puis définissez la propriété "Action de génération" comme "Ressource incorporée":

 enter image description here 

2
Ozlu

J'ai eu le même problème, grâce à Jay j'ai trouvé que c'était un trait d'union dans le nom du répertoire.

ProjectName.ResourceFolder.Sub-Directory devient ProjectName.ResourceFolder.Sub_Directory lorsque vous référencez le flux de ressources.

1
Aaron

Vous devez alors décharger votre solution.Ensuite, éditez le projet.

<EmbeddedResource Include="yourpath" />
0
Tiga
    First Unload the project and click on edit the project file. 

    Inside the project file make sure that the item you are fetching from the Assembly is included inside <EmbeddedResource> tag.

    Eg: 

         <ItemGroup>
          <EmbeddedResource Include="Template\ForExampleFile.html" />
         </ItemGroup>


    The files I added into the project were just in Content tag but not in the EmbeddedResource as shown below by default. Hence the stream was returning null.
    <ItemGroup>
        <Content Include="Template\ForExampleFile.html" />
  </ItemGroup>
0
Geek

Dans mon cas, le problème était que le code recherchant la ressource était dans un projet différent de celui de la ressource elle-même.

Vous ne pouvez accéder qu'aux ressources du même projet que le code. Je pensais pouvoir mettre toutes mes ressources dans le projet de page Web, mais j'ai également besoin d'images dans le projet de messagerie.

J'espère que cela aide quelqu'un dans la même situation que moi.

Je trouve vraiment utile d'appeler Assembly.GetExecutingAssembly().GetManifestResourceNames();.

0
AxelWass