Здравствуйте, Аноним, Вы писали:
А>Использую в программе WinAPI функцию UpdateResource: А>Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало
Вот чем мне нравятся отечественные программисты — спрашивают как сделать, им отвечают — "не надо так делать, это очень плохо, будут проблемы" (антивирус, файл залочится, не правильно это писать в exe файл и т.д.) и еще "есть простой, правильный, стандатный путь" (писать в AppData, в реестр, в UserData, в БД и т.д. и т.п.). Нет, они будут сидеть и решать совершенно левые проблемы, как же им все-таки заломать exe файл, потом таки решат и огребут проблем либо таки не решат, но в конце (месяца через два) наконец сделают так, как положено делать... И так как можно было бы сделать за пару дней... Я в восторге.
JR>Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.
Это он использует мою обертку, насколько я понял
правда, все равно неправильно
очень странная конструкция: Convert.ToUInt32("resource")
чего тут пробовать-то?
я вроде ясно тебе написал еще пару дней назад (да и другие знающие люди тоже это говорили), что Win32 ресурсы не имеют ничего общего с .NET ресурсами (кроме схожего названия и назначения)
соответственно, бесполезно пытаться работать с .NET ресурсами через Win32 API (и наоборот)
так что не знаю, зачем ты продолжаешь биться головой о стену
Как получить IntPtr на файл ресурса ???
От:
Аноним
Дата:
01.06.10 19:04
Оценка:
Использую в программе WinAPI функцию UpdateResource:
Здесь, пятый параметр IntPtr lpData, цитирую, "The resource data to be inserted into the file indicated by hUpdate", т.е. указатель на данные собственно и представляющие собой ресурс. Мне надо вставить ресурс(bitmap) в файл. Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало
А>там вполне рабочий код для работы с виндовыми ресурсами из под .NET
Попробовал сделать как вы сказали. Тупо скопировал текст программы WinRes.exe, и подставил свои пути. Программа пишет, что ресурс "успешно записан", но в файле куда я его писал ресурса нет. В связи с этим у меня появилась пару вопросов.
Во-первых. Что в функции UpdateResource
обозначает параметр pName. В статье написано, что это "числовой идентификатор ресурса". Но каким именно число должен быть этот идентификатор? В смысле, это какие-то предопределенные числа или я могу использовать любое число, которым будет помечен ресурс в файле, главное чтобы ресурса с таким-же идентификатором не было
Во-вторых. Я пытаюсь запихать ресурс в .exe-файл программы написанной на NET Framework v.4. Можно ли так делать? Точнее является-ли такой файл PE файлом
А>обозначает параметр pName. В статье написано, что это "числовой идентификатор ресурса". Но каким именно число должен быть этот идентификатор? В смысле, это какие-то предопределенные числа или я могу использовать любое число, которым будет помечен ресурс в файле, главное чтобы ресурса с таким-же идентификатором не было
Любое
А>Во-вторых. Я пытаюсь запихать ресурс в .exe-файл программы написанной на NET Framework v.4. Можно ли так делать? Точнее является-ли такой файл PE файлом
Да, EXE файл .Net это PE файл. А какой тип ресурса-то? Строки и иконки хранятся особо. Вообще, может лучше обновлять managed ресурсы?
Здравствуйте, adontz, Вы писали:
A>А какой тип ресурса-то? Строки и иконки хранятся особо.
Ресурс — bitmap. Но вообще нужно ещё добавлять/удалять текстовые файлы.
A>Вообще, может лучше обновлять managed ресурсы?
Хрен его знает. Вот я и хочу выяснить Модификации подвергается файл, в данный момент не исполняемый, поэтому какая ему разница. Наверное
Re[4]: Как получить IntPtr на файл ресурса ???
От:
Аноним
Дата:
02.06.10 14:33
Оценка:
Здравствуйте, adontz, Вы писали:
A>Да, EXE файл .Net это PE файл. А какой тип ресурса-то? Строки и иконки хранятся особо. Вообще, может лучше обновлять managed ресурсы?
По идее, файл-то Window'ый и соответственно с помощью WinAPI функций можно с ним, что угодно делать.
А на практике использую код ниже, но он что-то работать не хочет. Хотя я уже все по сто раз проверил Посмотрите свежим глазом может чего увидете
internal class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)] bool bDeleteExistingResources);
[DllImport("KERNEL32.DLL", EntryPoint = "UpdateResourceW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
public static extern bool UpdateResource(IntPtr hUpdate, string pType, UInt32 pName, UInt16 wLanguage, byte[] pData, UInt32 cbData);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool EndUpdateResource(IntPtr hUpdate, bool fDiscard);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern int GetLastError();
[STAThread]
private static void Main()
{
using (OpenFileDialog openDialog = new OpenFileDialog())
{
openDialog.Multiselect = false;
openDialog.Title = "Выберете PE-файл над которым будут проводиться операции...";
openDialog.Filter = "Исполняемые файлы (*.exe)|*.exe|Все файлы (*.*)|*.*";
if (openDialog.ShowDialog() != DialogResult.OK) return;
string targetFile = openDialog.FileName;
Assembly targetAssembly = Assembly.LoadFile(targetFile);
openDialog.Title = "Выберете ресурс...";
openDialog.Filter = "Растровое изображение (*.bmp)|*.bmp|Все файлы (*.*)|*.*";
if (openDialog.ShowDialog() != DialogResult.OK) return;
// Начинаем процесс записи ресурсов
IntPtr hUpdate = BeginUpdateResource(openDialog.FileName, false);
if (hUpdate != IntPtr.Zero)
{
using (BinaryReader binary = new BinaryReader(File.OpenRead(openDialog.FileName)))
{
long fileLength = (uint)(new FileInfo(openDialog.FileName)).Length;
byte[] resourceBytes = binary.ReadBytes((int)fileLength);
binary.Close();
// Записываем ресурсbool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
if (!bSuccess) Console.WriteLine("Ошибка #" + GetLastError());
// Заканчиваем запись
EndUpdateResource(hUpdate, !bSuccess);
}
}
string[] resources = targetAssembly.GetManifestResourceNames();
Console.WriteLine("Ресурсов в целевой сборке : {0}\n", resources.Length);
for (int i = 0; i < resources.Length; i++)
{
Console.WriteLine("{0}) {1}", i + 1, resources[i]);
}
}
Console.ReadLine();
}
}
Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.
"Нормальные герои всегда идут в обход!"
Re[7]: Как получить IntPtr на файл ресурса ???
От:
Аноним
Дата:
02.06.10 17:50
Оценка:
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, Аноним, Вы писали:
А>>>
JR>Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.
Да тут ещё один косячек нашелся OpenFileDialog.FileName возвращает путь к файлу с двумя \ в строке пути(например, C:\\Users\\...). А BeginUpdateResource принимает путь с одним \(например, C:\Users\...). Вот как-то надо от этого избавиться. А я забыл как
Re[8]: Как получить IntPtr на файл ресурса ???
От:
Аноним
Дата:
02.06.10 18:11
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Да тут ещё один косячек нашелся OpenFileDialog.FileName возвращает путь к файлу с двумя \ в строке пути(например, C:\\Users\\...). А BeginUpdateResource принимает путь с одним \(например, C:\Users\...). Вот как-то надо от этого избавиться. А я забыл как
Так пора отдохнуть. Гоню
Re[7]: Как получить IntPtr на файл ресурса ???
От:
Аноним
Дата:
02.06.10 19:13
Оценка:
Здравствуйте, Jolly Roger, Вы писали:
JR>Здравствуйте, Аноним, Вы писали:
А>>>
JR>Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.
А>Здесь, пятый параметр IntPtr lpData, цитирую, "The resource data to be inserted into the file indicated by hUpdate", т.е. указатель на данные собственно и представляющие собой ресурс. Мне надо вставить ресурс(bitmap) в файл. Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало
Небольшой офтопик.
Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами
А>>Это конечно, опечатка
А>что такое Convert.ToUInt32("resource")? А>здесь надо просто передать числовой идентификатор твоей картинки
А>вроде в статье в свое время я все достаточно подробно расписал А>правда, давно это было, я уж сам забыл про этот код
Блин братан, за обертку спасибо Но двумя топиками выше, я уже написал, ЧТО ЭТО ОПЕЧАТКА
Я передавал туда числа и использовал всевозможные варианты UpdateResource, но толку нет. Мы тут в другом топике уже родили, что managet-ресурсы видимо, именно ВИДИМО, т.к. ни чего конкретного ни кто не сказал, не удастся править managet-ресурсы функциями WinAPI. Хотя вроде как .exe файл создаваемый VS, должен быть PE-файлом, т.е. правиться UpdateResource. Хочешь попробуй, здесь
PD>Небольшой офтопик. PD>Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами
Тогда спрашивается зачем такие сложности-то? Записать в обычный XML или бинарник через сериализацию и т.д. и т.п. Зачем создавать себе сложности, делая DLL и потом ударно их решать?
Здравствуйте, Pavel_Agurov, Вы писали:
PD>>Небольшой офтопик. PD>>Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами
P_A>Тогда спрашивается зачем такие сложности-то? Записать в обычный XML или бинарник через сериализацию и т.д. и т.п. Зачем создавать себе сложности, делая DLL и потом ударно их решать?
Сложностей с работой с ресурсами Win32 в неуправляемых DLL никаких нет . Там все не просто, а очень просто.
А насчет XML или сериализации позволю себе поспорить. Если ты начнешь .bmp в XML переводить — объем возрастет прилично. Но не это главное
Хоть XML, хоть бинарник путем сериализации — как насчет произвольного доступа ? Win32 ресурсы — это ведь по сути библиотека ресурсов, в которых есть разные их типы, а для каждого типа может быть несколько ресурсов, и при этом всегда можно вытащить только тот ресурс, который нужен. Остальные даже не загружаются
Здравствуйте, Аноним, Вы писали:
А>Я передавал туда числа и использовал всевозможные варианты UpdateResource, но толку нет. Мы тут в другом топике уже родили, что managet-ресурсы видимо, именно ВИДИМО, т.к. ни чего конкретного ни кто не сказал, не удастся править managet-ресурсы функциями WinAPI. Хотя вроде как .exe файл создаваемый VS, должен быть PE-файлом, т.е. правиться UpdateResource. Хочешь попробуй, здесь
Похоже, что да. PE-фацл тут ни при чем — в нем ничего не говорится, какие секции должны в нем быть.
Классическая секция ресурсов в неуправляемых Win32 PE называется .rsrc. В управляемых PE она есть (запусти dumpbin), но, похоже, embedded resources попадают не туда, а в секцию .text. Почему так — спроси MS.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хоть XML, хоть бинарник путем сериализации — как насчет произвольного доступа ? Win32 ресурсы — это ведь по сути библиотека ресурсов, в которых есть разные их типы, а для каждого типа может быть несколько ресурсов, и при этом всегда можно вытащить только тот ресурс, который нужен. Остальные даже не загружаются
Offtop: Да, особенно просто решается тривиальная задача выгрузки .bmp или строк из ресурса в файл.
Здравствуйте, SaZ, Вы писали:
SaZ>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Хоть XML, хоть бинарник путем сериализации — как насчет произвольного доступа ? Win32 ресурсы — это ведь по сути библиотека ресурсов, в которых есть разные их типы, а для каждого типа может быть несколько ресурсов, и при этом всегда можно вытащить только тот ресурс, который нужен. Остальные даже не загружаются
SaZ>Offtop: Да, особенно просто решается тривиальная задача выгрузки .bmp или строк из ресурса в файл.
Offtop так offtop
В начале 90-х заказали мне написать электронный учебник по теории вероятности. Интернета в Омске тогда не было, и про HTML я ничего не знал. Знал бы — наверное, хватило бы наглости написать свой броузер с HTML , но поскольку я не знал, то придумал свой язык разметки гипертекста, который ни за что не покажу сейчас никому . Написал гипертекстовую систему с двумя фреймами (для основного текста и для примеров), всплывающими окнами (для определений), закладки, историю вперед-назад и т.д. В общем, мне и сейчас не стыдно за то, что я тогда сделал, тем более. что делалось это на чистом Win16, потому что MFC тогда у нас не было и я про нее тоже не знал (а писал под BC 3.1, потом под BC 4.5 переводил в Win32).
И возник вопрос — где тексты хранить ? А также картинки. База данных — я и сейчас бы не стал, потому что в применении к этому учебнику прицепить даже Access или тогдашний Paradox/FoxPro — все равно, что к велосипеду пристроить ракетный двигатель. Хранить в виде текстовых файлов — так их несколько сот, а вдруг какой-то удалят по ошибке (а то и хуже — отредактируют ), мне что, проверять на целостность весь набор файлов ? Подумал я и слепил из них DLL с ресурсами нестандартного вида. Дальше все просто — FindResource, LoadResource, LockResource, SizeOfResource, и вот он у тебя как на ладони. А картинки еще проще — LoadBitmap и все.
Так что ресурсы Win API — дело хорошее. Зачем их убрали в .Net — понять не могу.