Ресурсы ClassLibrary в проекте .NET 8

Я хочу переместить свои ресурсы, файлы Images и Strings.resx из моего проекта WPF в библиотеку классов.

Таким образом, проект, не WPF, может использовать тот же проект.

Для этого я создал новую библиотеку классов и переместил файлы в новый проект, убедившись, что действие сборки для изображений — это ресурс, как это было в проекте WPF.

Затем я заметил, что мои изображения не включены в файл *.dll и механизм «ресурсов» не работает.

Когда я делаю то же самое, НО, с таргетингом библиотеки классов .NET Framework 4.8, а не .NET 8.0, все работает так, как задумано.

Я также заметил, что когда я определяю <UseWPF>true</UseWPF> в своей библиотеке классов .NET 8.0, он также работает так, как задумано.

К сожалению, найденные обходные пути не работают для меня, так как я не хочу, чтобы .NET Framework 4.8 и UseWpf включали нежелательные зависимости в проект, отличный от wpf, например. Blazor Project, когда я делюсь библиотекой классов.

Я проверил недостающие ресурсы с помощью dotPeek, вот скриншот, на котором вы можете увидеть разницу между двумя целевыми платформами:

Система сборки с UseWPF по умолчанию добавляет png как <EmbeddedResource/> и без как <None />... Вам нужно <None Remove = "path/image.png" /> а затем <EmbeddedResource Include = "path/image.png" /> внутри <ItemGroup>

Selvin 26.06.2024 10:06

@Selvin - Я думаю, вы путаете Resource и EmbeddedResource, см., например. stackoverflow.com/questions/9419611 - в моем проекте cs действие сборки определено как ресурс <ItemGroup> <Resource Include = "Images\*.*" /> </ItemGroup> - и да, библиотека классов .NET 8 работает со встроенными ресурсами, но WPF не знает изображений, поскольку ищет ресурсы

Rand Random 26.06.2024 10:26

@Selvin - вот скриншот, показывающий мою проблему - i.sstatic.net/IYSj9lBW.png

Rand Random 26.06.2024 10:43
ClassLibrary2 работает либо путем объявления UseWPF ИЛИ изменения целевой платформы на net48, но оба решения нежелательны.
Rand Random 26.06.2024 10:45

@RandRandom, вы хотите создать общую библиотеку классов для изображений как с .NET Framework 4.8, так и с .NET 8.0?

Mustafa Mutasim 26.06.2024 10:45

@MustafaMutasim - нет, общая библиотека между проектом .NET 8 wpf и, например. проект .NET 8 blazor - оба .NET 8, НО разные типы проектов, например. рабочий стол и консоль или рабочий стол и Интернет, или рабочий стол Windows и терминал MacOS

Rand Random 26.06.2024 10:46

@MustafaMutasim - и я не могу настроить .net framework 4.8 или использовать UseWPF, когда библиотеку классов следует использовать на MacOs

Rand Random 26.06.2024 10:49

@RandRandom, можешь, я опубликую свой ответ на WPF и MAUI ты можешь начать с него

Mustafa Mutasim 26.06.2024 10:52

@RandRandom это как-то работает

Selvin 26.06.2024 11:23

@Selvin - как я уже сказал, EmbeddedResource действительно работает в библиотеке классов, НО я не могу использовать его в приложении WPF, потому что оно его не найдет, потому что ищет ресурс. посмотрите еще раз: i.sstatic.net/IYSj9lBW.png - где вы можете видеть, что WPF загружает изображение только в том случае, если оно объявлено как Resource, а UseWPF объявлен (ClassLibrary2).

Rand Random 26.06.2024 11:35

@RandRandom EmbeddedResource используется для g.resx, а не для изображения... изображение находится в файле resx (в моем последнем «примере изображения»)... добавьте «g.resx» типа Resource в проект, удалите, отключите генерацию кода и удалите g Файл .Designer.cs... добавить изображение в файл resx... изменить имя изображения в resx

Selvin 26.06.2024 11:37

@Selvin - окей, извини, похоже, это я недостаточно внимательно рассмотрел твое изображение, я попробую

Rand Random 26.06.2024 11:40

ок, без прикольного g.resx имени... можно обойтись <ItemGroup> <EmbeddedResource Update = "Resource.resx"> <LogicalName>$(AssemblyName).g.resources</LogicalName> </EmbeddedResource> </ItemGroup> обычным Resource.resx

Selvin 26.06.2024 11:43
selvin.pl/so/ResTest.zip
Selvin 26.06.2024 11:46

@Selvin - спасибо за идею, очень интересно - я могу проверить, что ILSpy показывает изображение, НО dotPeek не распознает его, как и WPF - так что, к сожалению, по неизвестной причине это не работает - может быть, вы есть идея, почему WPF, похоже, не нравится этот подход? i.sstatic.net/c9PmlugY.png

Rand Random 26.06.2024 12:26

Требуется ли встраивание файлов изображений в сборку? В противном случае вы можете установить для их действия Build Action значение Content и загружать их из WPF по siteoforigin URI.

Clemens 26.06.2024 12:37

единственная разница - <data name = "images/logo.png" mimetype = "application/x-microsoft.net.object.binary.base64">‌​<value> и <data name = "images/logo.png" type = "System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"><value> ... это глупо ... это работает в VS, но не в исполняемом файле ... кажется, здесь проблема?

Selvin 26.06.2024 12:53

@Клеменс - не совсем, пока WPF может с ними справиться, мне действительно все равно - единственная причина, по которой они являются ресурсами, заключается в том, что именно так вы и должны это делать.

Rand Random 26.06.2024 12:54

Хорошо, просто добавьте файлы изображений в проект библиотеки, установите для их действия «Сборка» значение Content и «Копировать в выходной каталог» — Copy .... Предполагая, что они находятся в папке проекта с именем «Изображения», загрузите их <Image Source = "pack://siteoforigin:,,,/Images/ImageFile.jpg"/>.

Clemens 26.06.2024 13:03

лол... разница в один байт i.sstatic.net/CU7wbzur.png в .resource файле между UseWPF и моим способом... это действительно глупо (я изменяю этот один байт в dll, и теперь он отображается в dotPeek)

Selvin 26.06.2024 14:00

@Clemens - попробовал вашу идею, и, похоже, она работает с изображениями, определенными в XAML на корневом уровне, но не в подпапке, например. Controls\MyCustomControl.xaml если у этого MyCustomControl.xaml есть изображение, оно его не найдет. Прочитав некоторую документацию, я считаю, что это потому, что оно будет искать изображение по адресу Controls\Image\abc.png вместо того, чтобы идти в корень и искать там Controls\abc.png - не удалось найти правильный синтаксис, чтобы всегда смотреть в корень, возможно ли это?

Rand Random 26.06.2024 14:52

Вы имеете в виду папку проекта с именем Controls, которая содержит MyCustomControl с изображением с URI источника siteoforigin? Это все еще работает для меня.

Clemens 26.06.2024 14:58

@Clemens - пытался воспроизвести проблему в фиктивном проекте, кажется, мой предыдущий диагноз был неправильным, и проблема находится в другом месте, если я смогу ее успешно воспроизвести, я вернусь к вам

Rand Random 26.06.2024 15:10

@RandRandom Наконец-то я нашел решение, которое, кажется, работает

Selvin 26.06.2024 16:18

@Selvin - посмотрю завтра, спасибо за преданность делу

Rand Random 26.06.2024 16:37

Кстати, вы можете настроить таргетинг на несколько фреймворков в одном проекте <TargetFrameworks>net8.0;net8.0-windows</TargetFrameworks> и добавить UseWPF условно <PropertyGroup Condition = " '$(TargetFramework)' == 'net8.0-windows' " > <UseWPF>true</UseWPF> </PropertyGroup>, тогда, если вы добавите ссылку PROJECT в проект blazor, он будет использовать net-8.0, а не net8.0-windows (если вам не нужен этот ресурс изображения в blazor)

Selvin 26.06.2024 16:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
26
307
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Наконец-то заработало...

С изображением logo.png в images/logo.png этот файл csproj должен работать:

<Project Sdk = "Microsoft.NET.Sdk">

    <Import Project = "..\targets\Microsoft.WinFX.targets" Sdk = "Microsoft.NET.Sdk.WindowsDesktop" />

    <PropertyGroup>
        <TargetFrameworks>net8.0</TargetFrameworks>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <None Remove = "Images\Logo.png" />
        <Resource Include = "Images\Logo.png" />
    </ItemGroup>
    
</Project>

Microsoft.WinFX.targets позволит скомпилировать <Resource /> элементы в $(AssemblyName).g.resources так же, как и в UseWPF/UseWindowsForms НО!!! не буду добавлять никаких ссылок

Разница в один байт, о которой я говорил в комментариях, заключается в том, что wpf/winforms использует System.IO.PinnedBufferMemoryStream, а не System.Byte[] для «сериализации» изображения.

Пример проекта

Спасибо, решение, похоже, работает просто великолепно. Просто небольшое замечание, которое вызвало проблему с моей стороны. Порядок строки <Import Project... имеет значение. В моем приложении я устанавливаю <AssemblyName>MyFancyName</AssemblyName> строка импорта должна появиться ПОСЛЕ изменения имени сборки.

Rand Random 27.06.2024 09:51

Другие вопросы по теме