Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Запись в себя


Автор: yarus88 17.5.2010, 10:02
Люди добрые подскажите.
Нужно создать экзешник который при запуске сам в себя записывает информацию, как это можно реализовать? 

Автор: Partizan 17.5.2010, 11:53
yarus88, какую информацию, зачем?

Автор: yarus88 17.5.2010, 19:33
дату последнего открытия.... задание такое.....

Автор: jonie 17.5.2010, 22:22
yarus88, в windows файл блокируется на запись на время выполнения (осталось еще со времен DOS-а). Вам либо надо делать копию себя и "перезапускаться" либо искать в таблицах лоченых дескрипторов свой (что далеко не тривиальная задача и очень завязана на версию винды).....
В общем простой ответ - копировать себя и из копии что надо делать.

Автор: Heinzz 18.5.2010, 08:44
Однако не стоит спешить запускать программу повторно сразу, подождите 7сек. Это конечно можно обойти, но...
Код

class Program
    {
        static string dir = Directory.GetCurrentDirectory();
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Last access time\t" + File.GetLastAccessTime(dir + "\\SaveMe.exe"));
                Console.ReadKey();

                //Main Program

                if (File.Exists(dir + "\\SaveMeCopy.exe"))
                {
                    File.Delete(dir + "\\SaveMeCopy.exe");
                }
                File.Copy(dir + "\\SaveMe.exe", dir + "\\SaveMeCopy.exe");
                Process p = new Process();
                ProcessStartInfo info = new ProcessStartInfo(dir + "\\SaveMeCopy.exe", "Copy");
                info.WindowStyle = ProcessWindowStyle.Hidden;
                p.StartInfo = info;
                p.Start();
            }
            else
            {
                switch (args[0])
                {
                    case "Copy":
                        System.Threading.Thread.Sleep(3000);
                        File.SetLastAccessTime(dir + "\\SaveMe.exe", DateTime.Now);
                        Process p = new Process();
                        ProcessStartInfo info = new ProcessStartInfo(dir + "\\SaveMe.exe", "DeleteCopy");
                        info.WindowStyle = ProcessWindowStyle.Hidden;
                        p.StartInfo = info;
                        p.Start();
                        break;

                    case "DeleteCopy":
                        System.Threading.Thread.Sleep(3000);
                        File.Delete(dir + "\\SaveMeCopy.exe");
                        break;
                }
            }
        }
    }

Автор: yarus88 18.5.2010, 22:24
Heinzz, огромнейшее тебе спасибо!
Тока есть пару вопросов:
1) Зачем нам ждать 7 секунд?
2)что такое args.Length == 0 и a[rgs[0], за что они отвечают?

Автор: Heinzz 19.5.2010, 08:19
перезаписи требуют какого-то времени.
args - массив аргументов командной строки

Автор: jonie 19.5.2010, 12:07
Heinzz, использовать мьютексы (или семафоры или др. средства синхронизации) вполне возможно, нежели "ждать 7 секунд"...

Автор: Heinzz 19.5.2010, 15:54
было бы интересно посмотреть пример. Я ими никогда не пользовался smile 

Автор: jonie 20.5.2010, 01:10
эх и эх.. а еще MCTS (я правди никогда не верил особо сертификатам)...
Код

    class Program
    {
        private const string semaphoreName = "semaphore";
        
        //обозначения:
        //сервер - тот кто запускает (первый экземпляр)
        //клиент - запускаемый вторым
        static void Main(string[] args)
        {
            if(args.Length>0)
            {
                //я клиент!
                //эумулятор длительной операции
                Thread.Sleep(10000);

                //уведомляем сервер что мы всё сделали
                Semaphore sem = Semaphore.OpenExisting(semaphoreName);
                sem.Release();
                //теперь сервер
            }
            else
            {
                //я сервер
                Semaphore sem = new Semaphore(0, 1, semaphoreName);

                Process p = new Process(); 
                ProcessStartInfo info = new ProcessStartInfo(Assembly.GetExecutingAssembly().Location, "ты_клиент");
                p.StartInfo = info;
                p.Start();
                //ждем пока запустится

                Console.WriteLine("Waiting....");
                sem.WaitOne();
                Console.WriteLine("All DONE!");
            }
        }
    }

ну примерно так...
конечно, стоит делать следующую штуку:
1) копируем себя
2) запускаем копию передав аргументом свое местоположение
3) выходим убедившись что копия запустилась (как раз семафор их примера поможет)
4) копия делает изменения
5) копия запускает сервер с параметром "всё сделано" (параметр нужен чтобы сервер еще раз не повторил итерацию начиная с п1)
....

Автор: Heinzz 20.5.2010, 20:39
что-то семафоры не сообщают когда файл разлочится smile таймаут нужен всеравно?

Автор: jonie 20.5.2010, 22:14
Heinzz, семафор умрет (с эксепшеном) при ожидании в клиенте, когда винда выгрузит процесс, владеющим им (сервер) (если сам сервер не зарелизит его)... чуете чем пахнет?) Мы можем с бОльшой долей вероятности сказать что после этого момента родительский экзешник будет освобожден если не сразу, то "почти сразу" - а дальше начинать писать (или отлочивать семафор перед выходом самым, без эксепшенов чтобы) .... просто при записи надо делать цикл в три итерации с задержкой (небольшой, типа i*500 мсек) при ошибке....

Автор: Heinzz 22.5.2010, 19:33
Цитата(jonie @  20.5.2010,  22:14 Найти цитируемый пост)
просто при записи надо делать цикл в три итерации с задержкой (небольшой, типа i*500 мсек) при ошибке....

получается что нам здесь семафор и не нужен?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)