как вшить текстовый файл в экзешник? в C# (VS 2008)
Я прочитал статью Выдёргивание и сохранение ресурсов в DLL или EXE. - она как бы четко по теме. но написана не на C#. и показалась мне замудренной. может от недостатка моих знаний.
и я подумал - может в VS 2008 есть способы сделать это проще, без создания своих процедур и т.п.
если кто знает - подскажите пожалуйста.
Шаг 45 - Создаем файл с ресурсами строк
Шаг 47 - Присоединяем файл ресурсов к exe
А если по-серьезней, то:
http://support.microsoft.com/kb/84062
Мысль такая:
Хедер exe'шника состоит из конкретного числа int'ов, по которым можно вычислить конец файла. И далее прочесть то, что после него.
Под MS-DOS файл приклеивали так:
Только вот применимо ли это к c#.
только когда делаю все по инструкции - выдается следующая ошибка
Resgen.exe resourse.txt не является внутренней или внешней командой, исполняемой программой или пакетным файлом
то, что выдается строка Resgen.exe resourse.txt наверное говорит о том, что bat-ник срабатывает. но проблема именно с Resgen.exe
Как вариант: присвоить переменной содержимое файла.
Значит resgen.exe то ли нет, то ли не видно.
Если 3.5, он может быть где-то здесь: C:\Program Files\Microsoft SDKs\Windows\bin
Если 2.0, то C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin
В крайнем случае он есть .NET Framework SDK 3.5. Кстати он весит 4 гига. А resgen всего ~49кб.
Второе название: ResXtoResources.exe
Можно просто набирать в консоли:
Ну тогда может быть стоит зайти в свойства проекта, там есть вкладка ресурсов - добавляете какие нужны.
using System.Resources;
namespace ResDemo
{
class MainClass
{
public static void Main(string[] args)
{
ResourceWriter rw = new ResourceWriter("demo.resx");//будет в папке с программой
rw.AddResource( "Title", "Professional C#" );
rw.AddResource( "Chapter", "Localization" );
rw.AddResource( "Author", "Christian Nagel" );
rw.AddResource( "Publisher", "Wrox Press" );
rw.Close();
Console.WriteLine("Hello World!");
}
}
}
Взято и переделано отсюда:
Локализация. Создание, генерация и использование ресурсных файлов:
http://www.rsdn.ru/article/dotnet/csprof2005_localization.xml#EWKAC
Создание, генерация и использование ресурсных файлов:
http://www.rsdn.ru/article/dotnet/csprof2005_localization.xml#EWKAC
Для решения задачи локализации, либо когда над проектом работает группа из программистов и дизайнеров/переводчиков этот подход является наиболее правильным (использование ресурсных файлов)!
Однако топик-стартеру проще и удобнее заюзать средства, которые есть в Visual Studio, чем генерить ресурсные файлы вручную.
P.S. про ResourceWriter не знал, интересно в каких случаях ресурсы надо генерировать в программе? =)
За системный подход ловите плюс =)
Вариант с использованием специальных папок для хранения настроек приложения не подойдет?
http://habrahabr.ru/blogs/development/70922/
Вариант с использованием специальных папок для хранения настроек приложения не подойдет?
http://habrahabr.ru/blogs/development/70922/
я думал над этим... наверно перепишу часть кода что бы в потоке работала без файлов... а программа не может в ходе своего выполнения добавлять в себя ресурсы или менчть их ?
не знаю, то ли я туплю то ли что. но не получается у меня применить приведенные подсказки :(
я в ресурсах сделал - Добавить новый текстовый файл. у меня появился текстовый файл чистый. я в него копипастнул свой файл. в результате смотрю - экзешник прибавил в весе на величину файлика. а самого файла нигде и не видно. как раз то что нужно. (только у меня не получается обратиться к его данным).
но неужели нельзя без всяких заморочек , строкой вроде изначальной
взять и считать весь этот файл из ресурса?
я вот так юзаю а там в потоке уже че надо то и делаю...
Вот только можно ли потом обратно в этот ресурс чего нибудь записать ?
когда дохожу до
Mynamespace.Properties.Resources. - жду что в выпадающем меню выпадет мой TextFile.txt, но он не выпадает. Среди ресурсов для выбора появляются только пара иконок для кнопок и еще что-то.
сразу говорю, что я уже подключил эти библиотеки
using System.Resources;
using System.Reflection;
using System.Threading;
Соединения файла EXE и ресурсов производиться при компиляции. Это делается путем использованию ключа /res при компиляции. Вот пример BAT файла:
но не понятно, где размещать этот файл. я разместил в корневой файле сам файл ресурсов и батник а в батнике прописал:
csc /res:resource.resources Program.cs
у меня вообще несколько файлов cs в папке. я пробовал прописывать по разные. пробовал запускать батник из папки с проектом. из папки Debug еще может откуда-то.
но отладчик выдает ошибку
Ты зачем мою то ставишь? у тебя своя должна быть! название другое !
конечно же у меня названия другие. просто твой пример вставил для наглядности.
То же самое, только на английском:
Решение:
заменить на
В названии файла и исходниках тоже поменять.
Под MonoDevelop 2.0 скомпилилось, однако, там уже своя ошибка:
Это говорит о том, что нужно использовать для компиляции профиль 2.*
Т.е. использовать не mcs, а gmcs.
p.s. man mcs
using System.Resources;
using System.Reflection;
namespace ResDemo
{
class MainClass
{
public static void Main(string[] args)
{
ResourceManager rm;
Assembly assembly = Assembly.GetExecutingAssembly();
rm = new ResourceManager( "demo.en-US", assembly );
Console.WriteLine(rm.GetString("Author"));
}
}
}
если не ответите, или ответ будет отрицательным, тогда буду уже дальше с ресурсами разбираться.
просто сегодня еще одна задача появилась , которая мне покоя не дает. с утра не могу разобраться с ней.
Есть более простой вариант - см. третью страницу темы.
Программа №1. Генерация файла ресурсов.:
using System.Resources;
using System.IO;
namespace ResDemo
{
class MainClass
{
public static void Main(string[] args)
{
string[] file_content=new string[300];
file_content=File.ReadAllLines("base.txt");
ResourceWriter rw = new ResourceWriter("demo.en-US.resources");//будет в папке с программой
rw.AddResource("Title",file_content);//см.далее.
rw.Close();
}
}
}
base.txt выглядит так, и находится в папке с программой:
Компилируем и запускаем программу №1.
Программа №2. Чтение из файла ресурсов.:
using System.Resources;
using System.Reflection;
namespace ResDemo
{
class MainClass
{
public static void Main(string[] args)
{
string[] file_content=new string[300];
ResourceManager rm;
Assembly assembly = Assembly.GetExecutingAssembly();
rm = new ResourceManager( "demo.en-US", assembly );
file_content=(string[])rm.GetObject("Title");
Console.WriteLine(file_content[0]);
}
}
}
Переносим demo.en-US.resources в папку с программой №2.
Компилируем:
или
gmcs /res:demo.en-US.resources Main.cs
При запуске Main.exe, выводится строка из base.txt.
Имена ресурсов должны совпадать:
csc /res:demo.en-US.resources Main.cs
ResourceWriter rw = new ResourceWriter("demo.en-US.resources");
Иначе снова появится ошибка культуры.
Я прочитал статью Выдёргивание и сохранение ресурсов в DLL или EXE. - она как бы четко по теме. но написана не на C#. и показалась мне замудренной. может от недостатка моих знаний.
и я подумал - может в VS 2008 есть способы сделать это проще, без создания своих процедур и т.п.
если кто знает - подскажите пожалуйста.
Вот вы развели тут балаган....
1) Находим каталог Properties в дереве проекта
2) Тыкаем дважды на Resources.resx
3) Выбераем в меню Add Resource опцию Add Existing File...
4) Находим txt файл, например sample.txt (хорошо его бы разместить вместе с решением и добавить в соответствующий проект)
5) VS автоматически создаст код для загрузки этого ресурса.
В коде можно обращаться к ресурсу через статическое свойство (sample) член класса MyProject.Properties.Resources.
З.Ы. В #D3.0 аналогично.
using System.Resources;
using System.Text;
using System.Reflection;
namespace BaseReader
{
class MainClass
{
public static void Main(string[] args)
{
Assembly a = Assembly.GetExecutingAssembly();
byte[] txtStream = new byte[32];
a.GetManifestResourceStream("base.txt").Read(txtStream,0,32);//читаем 32 байта из base.txt.
string s = System.Text.Encoding.UTF8.GetString(txtStream);//преобразуем в строку.
Console.WriteLine(s);
}
}
}
Перед компиляцией base.txt пометить как "embed as source".
В коде можно обращаться к ресурсу через статическое свойство (sample) член класса MyProject.Properties.Resources.
В MonoDevelop 2.0 так не получается.
А также, видимо, в VS 2008, у топик-стартера.
1) Находим каталог Properties в дереве проекта
2) Тыкаем дважды на Resources.resx
3) Выбераем в меню Add Resource опцию Add Existing File...
4) Находим txt файл, например sample.txt (хорошо его бы разместить вместе с решением и добавить в соответствующий проект)
5) VS автоматически создаст код для загрузки этого ресурса.
В коде можно обращаться к ресурсу через статическое свойство (sample) член класса MyProject.Properties.Resources.
вот как раз про это я писал в посте №12, - не получается так обратиться к ресурсу почему-то
Mynamespace.Properties.Resources. - жду что в выпадающем меню выпадет мой TextFile.txt, но он не выпадает. Среди ресурсов для выбора появляются только пара иконок для кнопок и еще что-то.
сразу говорю, что я уже подключил эти библиотеки
using System.Resources;
using System.Reflection;
using System.Threading;
Описанный мною способ прекрасно работает в VS2008. Чем пользуетесь?
да, у меня тоже теперь работает благодаря вам. у меня тоже ВС2008.
просто в дереве проекта я не в тот файл .resx добавлял его. (в Form1.resx). А когда снова внимательно посмотрел вашу запись нашел именно то, что вы написали Resources.resx , добавил туда. теперь через точку добавляется.
Теперь ИмяПроекта.Properties.Resources.TextFile1 - содержит текст файла.
самое обидное, что я сам пытался это проделать прежде чем обращаться на форум. но почему-то добавлял ресурс не туда. и потом мы устроили этот "балаган".
один мой знакомый говорит, что не хорошо файл (а он у меня 6мб), помещать в ресурсы. прав ли он?
и еще - насколько легко будет посторонним людям вытащить файл из экзешника
один мой знакомый говорит, что не хорошо файл (а он у меня 6мб), помещать в ресурсы. прав ли он?
Зависит от задачи, например некоторые мини-игры (Eufloria) кучу текстур и звуков в ресурсах держат.
Элементарно :)
Автор, советую файлик держать в zip с нулевым сжатием (если критична скорость доступа к ресурсу). Самое оно, что бы подальше от глаз любопытных, запаролить архив.
А еще готичьнее - зашифровать текстовик и уже с ним таким макаром работать. Но первый способ проще, как по мне
теперь только возникла другая проблема.
у меня в проге используется библиотека Microsoft.mshtml.dll. и как я заметил, из-за этого у людей, у кого net frameworks 3.5 не установлен вылазила ошибка. Поэтому я скопировал файлик Microsoft.mshtml.dll в папку проекта и в References указал ссылку на этот файлик. С тех пор приложение стало работать на всех компах.
а теперь, когда я сделал всю прогу в один exe файл - опять та же ситуация - подскажите пожалуйста, как мне впихнуть файл Microsoft.mshtml.dll опять в проект, но уже в качестве ресурса, и потом подключить его.
я сейчас добавил его в Resourses.resx и пытался подключить так:
но что-то не получается
Задать References на файлик из resurses.resx .
а затем подключить его используя using <library_name>
только как это сделать? и надо ли делать именно это
Задать References на файлик из resurses.resx .
а затем подключить его используя using <library_name>
только как это сделать? и надо ли делать именно это
Глупости.
.NET позволяет "слить" код двух "чистых" сборок (т.е. содержащих исключительно управляемый код), но для этого нужны дополнительные телодвижения после компиляции:
1) Декомпилируем ildasm-ом полученный exe-шник и dll-файл.
2) Полученные исходники компилируем снова в один exe файл ilasm-ом (не забывая о ссылках).
Правда зачем это все, когда можно в системных требованиях написать: .NET 3.5sp1 (или распространять два файла), и это, скажу я вам, - нормально.
а у меня из-за отсутствия библиотеки не работает всего навсего 3 строки
IHTMLSelectionObject currentSelection = htmlDocument.selection;
IHTMLTxtRange range = currentSelection.createRange() as IHTMLTxtRange;
просто мне кажется намного приятнее, когда скачал один файлик exe и все работает.
без разных обновлений и т.п.
ведь к тому же программа работала, когда просто в папке с exe лежала библиотека - на всех компах прога работала. вот точно также бы ее внутрь exe теперь записать
а то, что вы написали пока не понятно :(
Пользователю на самом деле глубоко плевать сколько у программы файлов, лишь бы она свою задачу выполняла. Более того, никто просто exe не раздает - это или архив, или инсталлятор (что вообще-то тоже архив), а для архива без разницы сколько файлов - один или тысяча.
Следующим вопросом автора будет: Как вшить Windows в exe'шник:)
Автор, а вы не думали, что из-за ошибки чтения/записи при работе с "вшитыми" данными может произойти такая прекрасная вещь, как последующая неработоспособность вашего раздутого exe?
подловил :)
спасибо огромное всем , кто помогал.
я проработал 2 года 1с-ником. отстал от жизни маленько. вот начал осваивать си шарп.
опыт 1с конечно пригодился - ООП оно везде ооп. но и много нюансов конечно.
например - в 1с компилить ниче не надо. Классы создавать не надо. там уже приложение готовое. надо плагины только делать и т.п.
а тут все с нуля когда делаешь (с нуля относительно конечно, ведь VS 2008 очень не плохо помогает) - появляются разные вопросы.
Ваша адекватность поражает, я имею в виду, пожалуй, все ваши сообщения.
Прочитал тему...
раньше было так:
Сделал текстовый файл ресурсом.
Теперь пытаюсь сделать так:
После запуска программы в richTextBox1 ничего не отображается. Что я не так делаю? Как это можно реализовать? Раньше с ресурсами никогда не работал...