Страница 1 из 2
Ресурсы в .Net
Добавлено: 19 мар 2009, 10:40
Decoder
Недавно начал изучать платформу don't Net и сталкнулся с проблемой загрузки строки из ресурсов приложения. Если в Win32API это делается с помощью функции LoadString(), то в CLR-классах я так и не нашёл аналогичного метода. Попробовал через ResourceManager, но у меня ничего не получилось, непонятно какие параметры ему требуются для инициализации. Как быть?
Re: Ресурсы в .Net
Добавлено: 19 мар 2009, 18:54
WinMain
Понимаю тебя,
Decoder. Когда-то сам столкнулся с подобной задачей.
Суть в том, что нативные ресурсы обычных Win32-приложений в программах на don't Net практически не используются. Там хранятся лишь иконки и информация о версии файла, которые в "Проводнике" отображаются, да и их тоже в новых версиях Windows потом перестанут использовать. Вместо этого там используются ресурсы другого типа. У тебя в проекте должен быть файл с расширением
.resx, в котором и содержится текст с описанием ресурсов в виде данных XML. Потом этот файл компилируется в бинарный модуль с расширением
.resources, который и встраивается в исполняемый модуль приложения.
Я вместо класса ResourceManager использовал ResourceSet, а доступ к модулю исполняемого приложения получил через Reflection.Assembly...
В файле ресурсов должна быть строковая таблица хотя бы с одной строкой, обозначенная к примеру как "String1".
Вот как это выглядит в коде на C++/CLI
Код: Выделить всё
#include "stdafx.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Reflection::Assembly^ ass = // kiss my ass...
Reflection::Assembly::GetExecutingAssembly();
IO::Stream^ stream =
ass->GetManifestResourceStream(ass->GetManifestResourceNames()[0]);
Resources::ResourceSet^ rset = gcnew Resources::ResourceSet(stream);
Console::WriteLine(rset->GetString(L"String1"));
Console::Read();
//
return 0;
}
В результате на экране должен появиться текст строки String1 из ресурсов.
Но дело ещё в том, что в приложении может быть несколько ресурсных файлов, тогда вместо ass->GetManifestResourceNames()[0] нужно будет указать конкретный ресурсный нэйм-спэйс, в котором содержится вызываемая строка.
Re: Ресурсы в .Net
Добавлено: 20 мар 2009, 18:29
Decoder
Спасибо,
WinMain.
Я тут сам немного потренировался с ресурсами. Написал небольшую программку, которая выводит на экран имена ресурсных частей, входящих в исполняемый модуль...
Код: Выделить всё
#include "stdafx.h"
using namespace System;
int main(array<System::String ^> ^args)
{
Reflection::Assembly^ ass = // kiss my ass...
Reflection::Assembly::GetExecutingAssembly();
for each (String^ str in ass->GetManifestResourceNames())
{
Console::WriteLine(str);
}
Console::Read();
//
return 0;
}
Получается что имя ресурснй части совпадает с именем бинарного ресурсного файла, который встраивается в модуль приложения.
Re: Ресурсы в .Net
Добавлено: 01 авг 2009, 01:28
Decoder
Хочется ещё спросить на эту тему: можно ли использовать бинарные ресурсы .NET в обычных приложениях Win32 без поддержки CLR?
Например: строковые таблицы, как внешний ресурс.
Re: Ресурсы в .Net
Добавлено: 01 авг 2009, 12:49
WinMain
В принципе можно. Даже в ряде случаев это было бы более правильным решением, чем создавать отдельную DLL, содержащую некий набор внешних ресурсов.
Например: если создавать приложения с многоязычным пользовательским интерфейсом. Все текстовые строки вынести в отдельный файл и обращаться к нему в момент загрузки программы. При выборе другого языка, программа будет обращаться уже к другому ресурсному файлу.
Файл с XML-ресурсами .NET (расширение resx) можно включить и в обычный проект Win32 Application. При этом ресурсы данного файла можно будет редактировать всё тем же редактором Visual Studio, как если бы он использовался в проекте на C#. Мало того, этот файл .resx будет компилироваться вместе с другими файлами проекта, только потом полученный бинарный файл не будет встраиваться внутрь приложения (если конечно принудительно не включить его в состав ресурсов).
Сложность в том, что в составе Win32API нет специальных функций для работы с такими ресурсами (на самом деле функции имеются, но они работают через ядро .NET FrameWork). Поэтому нужно будет самому написать (или найти готовую) процедуру чтения данных из бинарных ресурсов .NET
Re: Ресурсы в .Net
Добавлено: 02 авг 2009, 12:33
Decoder
Интересно было бы найти готовую функцию. Но я не нашёл даже описания формата файла с расширением .resources, который получается после компиляции resx файла. Жаль, что хорошая идея может так и остаться всего лишь идеей.
Re: Ресурсы в .Net
Добавлено: 03 авг 2009, 21:18
WinMain
Ну а сам что... не можешь с бинарником разобраться? Неужели так сложно?
А вот и спецификация по формату этого файла...
http://msdn.microsoft.com/en-us/library ... 10%29.aspx
Re: Ресурсы в .Net
Добавлено: 04 авг 2009, 16:43
Romeo
Подход "разберись сам" плох по одной причине. Со временем формат бинарника может поменяться. В этом случае нам придётся менять и наш код. В то время, как если бы мы использовали стандартную функцию (имплементация которой была обязана поменяться вместе со сменой формата), то наш код бы остался без изменений и даже не потребовал рекомпиляции. Именно поэтому поиск стандартной функции куда более правилен, чем самостоятельный разбор бинаря.
Re: Ресурсы в .Net
Добавлено: 04 авг 2009, 17:03
WinMain
Кто бы спорил. Ну а что делать, если необходимый SDK не реализован на Win32API? Приходится таким вот образом выкручиваться.
С другой стороны, если использовать этот файл только внутри собственного приложения, то изменения его формата дадут о себе знать лишь при смене среды разработки, например: переход на Visual Studio 2010 и .NET FrameWork 4.0
У меня была схожая ситуация, когда мне нужно было ресурс окна диалога читать напрямую из бинарника. Я только тогда заметил, что бинарный формат диалогов в ресурсах VC++ 6.0 и VC++ 2005 заметно отличается.
Пока используешь функции Win32API, эти изменения остаются незаметными и на работе программы никак не сказываются.
Re: Ресурсы в .Net
Добавлено: 07 авг 2009, 21:09
Decoder
Спасибо, WinMain.
Я по твоей рекомендации написал процедуру чтения строковой таблицы из бинарного ресурса .Net
Данная процедура правильно работает только с теми бинарниками, в которых содержатся лишь строковые таблицы и никаких других ресурсов. В дальнейшем можно будет дописать эту процедуру для чтения других ресурсов и сделать её универсальной.