To jest aplikacja C # .NET 4.0:
Osadzam plik tekstowy jako zasób, a następnie próbuję wyświetlić go w oknie dialogowym:
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);
}
}
Rozwiązaniem jest MyProjSolution, a plikiem wykonywalnym jest MyProj.exe. Help.txt to zasób osadzony. Jednak strumień jest pusty. Próbowałem MyProjSolution.Help.txt i MyProjSolution.MyProj.Help.txt, ale wydaje się, że nic nie działa.
Odpowiedzi:
Możesz sprawdzić, czy zasoby są poprawnie osadzone przy użyciu
podczas debugowania. Spowoduje to wyświetlenie wszystkich (w pełni kwalifikowanych nazw) wszystkich zasobów osadzonych w zestawie, w którym jest zapisany kod.
Zobacz Assembly.GetManifestResourceNames () w witrynie MSDN.
Po prostu skopiuj odpowiednią nazwę i użyj jej zamiast tego, co zdefiniowałeś w zmiennej „resourceName”.
Uwagi - w nazwie zasobu rozróżniana jest wielkość liter i jeśli niepoprawnie osadziłeś plik zasobu, nie pojawi się on na liście zwróconej przez wywołanie GetManifestResourceNames (). Ponadto - upewnij się, że czytasz zasób z prawidłowego zestawu (jeśli używanych jest wiele zestawów) - zbyt łatwo jest pobrać zasoby z aktualnie wykonywanego zestawu, a nie z zestawu, do którego się odwołuje.
EDYCJA - .NET Core
Zobacz ten wpis SO, aby uzyskać szczegółowe informacje na temat osadzania przy użyciu platformy .NET Core.
Pobieranie informacji manifestu wygląda podobnie - po prostu użyj go,
this.GetType().GetTypeInfo().Assembly.GetManifestResourceNames()
aby pobrać manifest z zestawu, w którym wykonywany jest kod.Jeszcze nie wymyśliłem, jak zrobić odpowiednik
Assembly.GetExecutingAssembly()
w .NET Core! jeśli ktoś wie - daj mi znać, a zaktualizuję tę odpowiedź.źródło
Miałem podobny problem, najpierw sprawdź, czy plik jest zawarty w twoim projekcie, a następnie przejdź do właściwości i ustaw akcję kompilacji tego pliku na Zasób osadzony. to działało dla mnie.
źródło
DefatultNameSpace.Infrastructure.Help.txt
. Domyślna przestrzeń nazw na stronie właściwości projektu iInfrastructure
będzie folder, który plik jest wWłaściwość „Build Action” osadzonego pliku powinna być ustawiona na „Embedded Resource”, aby poprawnie uruchomić wiersz podany poniżej:
Kliknij plik prawym przyciskiem myszy, kliknij właściwość, a następnie ustaw właściwość „Build Action” na „Embedded Resource”:
źródło
Oto przyczyna mojej wartości zerowej.
http://adrianmejia.com/blog/2011/07/18/cs-getmanifestresourcestream-gotcha/
GetManifestResourceStream
Metoda będzie zawsze powracaNULL
jeśli właściwość zasobu „zbudowany działania” nie jest ustawiony na „zasobu osadzonego”Po ustawieniu tej właściwości ze wszystkimi potrzebnymi plikami
assembly.GetManifestResourceStream
zaczyna zwracać poprawny strumień zamiastNULL
.źródło
Tylko ostrzeżenie.
Nie mogłem uzyskać dostępu do mojego pliku jako zasobu osadzonego, mimo że określiłem, że był i mimo że miał tę właściwość Build Action. Zmarnowałem dużo czasu na walenie głową. Osadziłem plik kodu csharp z .txt dołączonym do jego nazwy (xxx.cs.txt). Z jakiegoś powodu metody GetManifestResourceNames () i GetManifestResourceStream () nie zobaczą pliku z .cs w nazwie.
Zmieniłem nazwę po prostu na xxx.txt i wszystko było w porządku.
Dziwne.
źródło
Resource
ale nieEmbedded Resource
, co czyni go jeszcze dziwniejszym ... Usunięcie.cs.
z nazwy sprawia, że działa. Argh.Miałem ten sam problem, dzięki Jayowi stwierdziłem, że w nazwie katalogu były myślniki.
ProjectName.ResourceFolder.Sub-Directory
staje się,ProjectName.ResourceFolder.Sub_Directory
gdy odwołujesz się do strumienia zasobów.źródło
W moim przypadku problem polegał na tym, że kod szukający zasobu znajdował się w innym projekcie niż sam zasób.
Możesz uzyskać dostęp tylko do zasobów, które są w tym samym projekcie, w którym znajduje się kod. Pomyślałem, że mogę umieścić wszystkie moje zasoby w projekcie strony internetowej, ale potrzebuję również obrazów w projekcie poczty.
Mam nadzieję, że pomoże to komuś w takiej samej sytuacji, w jakiej byłem.
Uważam, że powołanie jest naprawdę przydatne
Assembly.GetExecutingAssembly().GetManifestResourceNames();
.źródło
W przypadku, gdy pomaga to komukolwiek innemu, upewnij się, że
Assembly.GetExecutingAssembly()
linia jest wywoływana z tego samego zestawu, który ma osadzone zasoby.źródło
Prostym i usprawnionym rozwiązaniem jest posiadanie tej klasy bazowej :
Następnie podczas dodawania zasobu tworzysz klasę czytnika C # w tym samym folderze:
gdzie klasa czytelnika MyResource.cs jest bardzo prosta:
Zatem każdy zasób będzie miał klasę „shadow”, która wie, jak go poprawnie odczytać.
Oto jak odczytujesz zasób w swoim kodzie:
I jak sugerowały inne odpowiedzi, nie zapomnij ustawić „Zasobu osadzonego” we właściwości Akcja kompilacji pliku zasobów.
Zaletą tego jednolitego rozwiązania jest
źródło
źródło
Musisz zwolnić swoje rozwiązanie, a następnie edytować projekt, a następnie znaleźć folder i zmienić go w ten sposób:
źródło
Chociaż OP otrzymał GetManifestResourceStream zwracając NULL z zasobów w tym samym zestawie, niektóre odpowiedzi sugerowały, że gdy zasoby znajdują się w innym projekcie lub zestawie, nie można ich odzyskać i są uzasadnioną przyczyną zwracania wartości NULL przez GetManifestResourceStream.
To nieprawda, przynajmniej od 2011 roku; jak wskazałem w niektórych komentarzach w innym miejscu, Assembly.LoadFrom () lub typeof załatwiają sprawę iw rezultacie możesz uzyskać dostęp do zasobów, które są w innym projekcie.
Mam tutaj do zilustrowania umiarkowanie złożony przykład; to jest moja konfiguracja testowa:
Ścieżka do innego projektu:
Przechwycono tutaj:
A na Form1.cs z WinFormFramework określam za pomocą
tak:
Wynik wyświetlany w polu tekstowym:
Spędziłem kilka godzin, aby zrobić to dobrze; w tym celu musiałem często używać tych w Immediate Window:
Mam nadzieję, że to komuś pomoże
źródło
Prawdopodobnie musisz podać ścieżkę do pliku txt w
GetManifestResourceStream
parametrze lub możesz spróbować umieścić plik txt w tym samym katalogu, co plik wykonywalny. Mam nadzieję, że to pomoże!źródło