Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 01.06.10 19:04
Оценка:
Использую в программе WinAPI функцию UpdateResource:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);

Здесь, пятый параметр IntPtr lpData, цитирую, "The resource data to be inserted into the file indicated by hUpdate", т.е. указатель на данные собственно и представляющие собой ресурс. Мне надо вставить ресурс(bitmap) в файл. Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало
Re: Как получить IntPtr на файл ресурса ???
От: adontz Грузия http://adontz.wordpress.com/
Дата: 01.06.10 19:36
Оценка:
Здравствуйте, Аноним, Вы писали:

MemoryStream + Bitmap.Save + Marshal.AllocHGlobal + Marshal.Copy
A journey of a thousand miles must begin with a single step © Lau Tsu
Re: Как получить IntPtr на файл ресурса ???
От: Андрей Россия  
Дата: 02.06.10 06:10
Оценка:
Здравствуйте, Аноним, Вы писали:

skip

так будет правильнее
[DllImport("KERNEL32.DLL", EntryPoint="UpdateResourceW", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool UpdateResource(IntPtr hUpdate, UInt32 pType, UInt32 pName, UInt16 wLanguage, byte[] pData, UInt32 cbData);


// где-то в коде используется так:
//
using (BinaryReader reader = new BinaryReader(File.OpenRead(strResFile)))
{
  long nCount = new FileInfo(strResFile).Length;
  byte[] bytes = reader.ReadBytes((int)nCount);
  reader.Close();

  if (UpdateResource(hUpdate, nResType, nResID, 1049, bytes, (UInt32)nCount))
    Console.Write("Ресурс \"{0}\" успешно записан\n", strResFile);
}
Re: Как получить IntPtr на файл ресурса ???
От: Андрей Россия  
Дата: 02.06.10 06:16
Оценка:
Здравствуйте, Аноним, Вы писали:

skip

почитай вот это
Автор(ы): Алифанов Андрей
Дата: 25.02.2003
Данная статья описывает утилиту для записи Win32-ресурсов в файлы формата PE. Утилита в первую очередь предназначена для использования в проектах на Visual C# и VB.NET, хотя и не только :-)

там вполне рабочий код для работы с виндовыми ресурсами из под .NET
Re[2]: Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 02.06.10 12:36
Оценка:
Здравствуйте, Андрей, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>skip


А>почитай вот это
Автор(ы): Алифанов Андрей
Дата: 25.02.2003
Данная статья описывает утилиту для записи Win32-ресурсов в файлы формата PE. Утилита в первую очередь предназначена для использования в проектах на Visual C# и VB.NET, хотя и не только :-)

А>там вполне рабочий код для работы с виндовыми ресурсами из под .NET

Попробовал сделать как вы сказали. Тупо скопировал текст программы WinRes.exe, и подставил свои пути. Программа пишет, что ресурс "успешно записан", но в файле куда я его писал ресурса нет. В связи с этим у меня появилась пару вопросов.
Во-первых. Что в функции UpdateResource
public static extern bool UpdateResource(IntPtr hUpdate, string pType, UInt32 pName,
                                                 UInt16 wLanguage, byte[] pData, UInt32 cbData);

обозначает параметр pName. В статье написано, что это "числовой идентификатор ресурса". Но каким именно число должен быть этот идентификатор? В смысле, это какие-то предопределенные числа или я могу использовать любое число, которым будет помечен ресурс в файле, главное чтобы ресурса с таким-же идентификатором не было
Во-вторых. Я пытаюсь запихать ресурс в .exe-файл программы написанной на NET Framework v.4. Можно ли так делать? Точнее является-ли такой файл PE файлом
Re[3]: Как получить IntPtr на файл ресурса ???
От: adontz Грузия http://adontz.wordpress.com/
Дата: 02.06.10 13:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Во-первых. Что в функции UpdateResource

А>
А>public static extern bool UpdateResource(IntPtr hUpdate, string pType, UInt32 pName,
А>                                                 UInt16 wLanguage, byte[] pData, UInt32 cbData);
А>

А>обозначает параметр pName. В статье написано, что это "числовой идентификатор ресурса". Но каким именно число должен быть этот идентификатор? В смысле, это какие-то предопределенные числа или я могу использовать любое число, которым будет помечен ресурс в файле, главное чтобы ресурса с таким-же идентификатором не было

Любое

А>Во-вторых. Я пытаюсь запихать ресурс в .exe-файл программы написанной на NET Framework v.4. Можно ли так делать? Точнее является-ли такой файл PE файлом


Да, EXE файл .Net это PE файл. А какой тип ресурса-то? Строки и иконки хранятся особо. Вообще, может лучше обновлять managed ресурсы?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[4]: Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 02.06.10 13:37
Оценка:
Здравствуйте, 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();
        }
    }
Re[5]: Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 02.06.10 14:52
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>// Записываем ресурс
А>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>

Это конечно, опечатка
Re[6]: Как получить IntPtr на файл ресурса ???
От: Jolly Roger  
Дата: 02.06.10 17:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>
А>>// Записываем ресурс
А>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>


Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.
"Нормальные герои всегда идут в обход!"
Re[7]: Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 02.06.10 17:50
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Аноним, Вы писали:


А>>>
А>>>// Записываем ресурс
А>>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>>


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>Здравствуйте, Аноним, Вы писали:


А>>>
А>>>// Записываем ресурс
А>>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>>


JR>Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.


Нет, это не помогает
Re: Как получить IntPtr на файл ресурса ??? - OFFTOP
От: Аноним  
Дата: 02.06.10 19:22
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Использую в программе WinAPI функцию UpdateResource:

А>Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало

Вот чем мне нравятся отечественные программисты — спрашивают как сделать, им отвечают — "не надо так делать, это очень плохо, будут проблемы" (антивирус, файл залочится, не правильно это писать в exe файл и т.д.) и еще "есть простой, правильный, стандатный путь" (писать в AppData, в реестр, в UserData, в БД и т.д. и т.п.). Нет, они будут сидеть и решать совершенно левые проблемы, как же им все-таки заломать exe файл, потом таки решат и огребут проблем либо таки не решат, но в конце (месяца через два) наконец сделают так, как положено делать... И так как можно было бы сделать за пару дней... Я в восторге.
Re[6]: Как получить IntPtr на файл ресурса ???
От: Андрей Россия  
Дата: 03.06.10 03:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>>
А>>// Записываем ресурс
А>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>

А>Это конечно, опечатка

что такое Convert.ToUInt32("resource")?
здесь надо просто передать числовой идентификатор твоей картинки

вроде в статье в свое время я все достаточно подробно расписал
правда, давно это было, я уж сам забыл про этот код
Re[7]: Как получить IntPtr на файл ресурса ???
От: Андрей Россия  
Дата: 03.06.10 03:42
Оценка: +1
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, Аноним, Вы писали:


А>>>
А>>>// Записываем ресурс
А>>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>>


JR>Если имеется в виду стандартный тип ресурса BITMAP, то это не совсем то. Нужно объявить перегрузку bool UpdateResource(IntPtr hUpdate, Int32 pType, ...) и передать туда константу RT_BITMAP, которая равна 2.


Это он использует мою обертку, насколько я понял
правда, все равно неправильно

очень странная конструкция: Convert.ToUInt32("resource")
Re: Как получить IntPtr на файл ресурса ???
От: Pavel Dvorkin Россия  
Дата: 03.06.10 15:27
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Использую в программе WinAPI функцию UpdateResource:

А>
А>[DllImport("kernel32.dll", SetLastError = true)]
А>static extern bool UpdateResource(IntPtr hUpdate, string lpType, string lpName, ushort wLanguage, IntPtr lpData, uint cbData);
А>

А>Здесь, пятый параметр IntPtr lpData, цитирую, "The resource data to be inserted into the file indicated by hUpdate", т.е. указатель на данные собственно и представляющие собой ресурс. Мне надо вставить ресурс(bitmap) в файл. Как мне правильно получить этот указатель на bitmap-ресурс, что-бы все сработало

Небольшой офтопик.

Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами
With best regards
Pavel Dvorkin
Re[7]: Как получить IntPtr на файл ресурса ???
От: Аноним  
Дата: 03.06.10 20:21
Оценка:
Здравствуйте, Андрей, Вы писали:

А>>>
А>>>// Записываем ресурс
А>>>bool bSuccess = UpdateResource(hUpdate, "RT_BITMAP", Convert.ToUInt32("resource"), 1049, resourceBytes, (UInt32)fileLength);
А>>>

А>>Это конечно, опечатка

А>что такое Convert.ToUInt32("resource")?

А>здесь надо просто передать числовой идентификатор твоей картинки

А>вроде в статье в свое время я все достаточно подробно расписал

А>правда, давно это было, я уж сам забыл про этот код

Блин братан, за обертку спасибо Но двумя топиками выше, я уже написал, ЧТО ЭТО ОПЕЧАТКА
Я передавал туда числа и использовал всевозможные варианты UpdateResource, но толку нет. Мы тут в другом топике уже родили, что managet-ресурсы видимо, именно ВИДИМО, т.к. ни чего конкретного ни кто не сказал, не удастся править managet-ресурсы функциями WinAPI. Хотя вроде как .exe файл создаваемый VS, должен быть PE-файлом, т.е. правиться UpdateResource. Хочешь попробуй, здесь
Автор:
Дата: 03.06.10
точно описан порядок проведенного эксперимента.
Re[2]: Как получить IntPtr на файл ресурса ???
От: Pavel_Agurov Россия  
Дата: 04.06.10 07:50
Оценка:
PD>Небольшой офтопик.
PD>Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами

Тогда спрашивается зачем такие сложности-то? Записать в обычный XML или бинарник через сериализацию и т.д. и т.п. Зачем создавать себе сложности, делая DLL и потом ударно их решать?
Re[3]: Как получить IntPtr на файл ресурса ???
От: Pavel Dvorkin Россия  
Дата: 04.06.10 09:20
Оценка:
Здравствуйте, Pavel_Agurov, Вы писали:

PD>>Небольшой офтопик.

PD>>Из всех этих дискуссий о добавлении ресурсов в управляемый код у меня сложилось впечатление, что самое простое решение — добавить их в неуправляемую DLL, положить ее рядом с EXE и не морочить себе голову. Для доступа использовать Win32 функции работы с ресурсами

P_A>Тогда спрашивается зачем такие сложности-то? Записать в обычный XML или бинарник через сериализацию и т.д. и т.п. Зачем создавать себе сложности, делая DLL и потом ударно их решать?


Сложностей с работой с ресурсами Win32 в неуправляемых DLL никаких нет . Там все не просто, а очень просто.

А насчет XML или сериализации позволю себе поспорить. Если ты начнешь .bmp в XML переводить — объем возрастет прилично. Но не это главное

Хоть XML, хоть бинарник путем сериализации — как насчет произвольного доступа ? Win32 ресурсы — это ведь по сути библиотека ресурсов, в которых есть разные их типы, а для каждого типа может быть несколько ресурсов, и при этом всегда можно вытащить только тот ресурс, который нужен. Остальные даже не загружаются
With best regards
Pavel Dvorkin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.