Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
5 / 5 / 2
Регистрация: 04.04.2013
Сообщений: 44
1
.NET 4.x

Служба backup'a файла при перезаписи файла

31.05.2016, 20:55. Показов 1521. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток.
Появилась задача резервного копирования файла, которое должно происходить при перезаписи файла.
Простое приложение работает на ура, но было решено написать Windows-службу т.к. копирование происходит на сервере.
И тут возникла проблема: служба завершает свою работу когда доходит до копирования. Пробую на ОС Win7 x64
Подскажите, что может быть за косяк:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
public enum ServiceState
    {
        SERVICE_STOPPED = 0x00000001,
        SERVICE_START_PENDING = 0x00000002,
        SERVICE_STOP_PENDING = 0x00000003,
        SERVICE_RUNNING = 0x00000004,
        SERVICE_CONTINUE_PENDING = 0x00000005,
        SERVICE_PAUSE_PENDING = 0x00000006,
        SERVICE_PAUSED = 0x00000007,
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct ServiceStatus
    {
        public long dwServiceType;
        public ServiceState dwCurrentState;
        public long dwControlsAccepted;
        public long dwWin32ExitCode;
        public long dwServiceSpecificExitCode;
        public long dwCheckPoint;
        public long dwWaitHint;
    };
 
    
 
    public partial class MyNewService : ServiceBase
    {
        [DllImport("advapi32.dll", SetLastError=true)]
        private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
 
        int eventId = 0;
        public MyNewService()
        {
            InitializeComponent();
            
            eventLog1 = new System.Diagnostics.EventLog();
            
            
            if (!System.Diagnostics.EventLog.SourceExists("MySource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog");
            }
            
            eventLog1.Source = "MySource";
            eventLog1.Log = "MyNewLog";
        }
 
        protected override void OnStart(string[] args)
        {
            ServiceStatus serviceStatus = new ServiceStatus();
            serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
            serviceStatus.dwWaitHint = 100000;
            SetServiceStatus(this.ServiceHandle, ref serviceStatus);
 
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.Path = "D:\\watcher";
            watcher.NotifyFilter = NotifyFilters.LastWrite;
            
            watcher.Filter = "1.txt";
 
            watcher.Changed += new FileSystemEventHandler(OnChanged);
 
 
            watcher.EnableRaisingEvents = true;
 
            eventLog1.WriteEntry("In OnStart");
 
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Interval = 60000; // 60 seconds
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); 
            timer.Start();
 
            // Update the service state to Running.
            serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
            SetServiceStatus(this.ServiceHandle, ref serviceStatus);
        }
 
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information, eventId++);
        }
 
        static DateTime timeOld;
 
        private static void OnChanged(object source, FileSystemEventArgs e)
        { 
                FileInfo fi = new System.IO.FileInfo(e.FullPath);
                fi.CopyTo("D:\\watcher\\backup-" + DateTime.Now.ToUniversalTime().ToString() + ".txt",true);
                timeOld = DateTime.Now;
            
            Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
 
        }
 
        protected override void OnStop()
        {
            eventLog1.WriteEntry("In onStop.");
        }
 
        protected override void OnContinue()
        {
            eventLog1.WriteEntry("In OnContinue.");
        }
    }
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.05.2016, 20:55
Ответы с готовыми решениями:

Внесение изменений в XML без перезаписи всего файла
Такой вопрос есть приложение которое работает с данными в XML. Работает примерно таким образом : ...

Создание (сохранение) файла без перезаписи с добавлением цифры к имени файла
Как реализовать в программе возможность сохранения файла без удаления старого(одноимённого файла) ...

Даны два текстовых файла. Добавить в конец первого файла содержимое второго файла
Даны два текстовых файла. Добавить в конец первого файла содержимое второго файла.

Даны два текстовых файла. Добавить в начало первого файла содержимое второго файла
Даны два текстовых файла. Добавить в начало первого файла содержимое второго файла

5
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2016, 00:13 2
Лучший ответ Сообщение было отмечено mcSHLANG как решение

Решение

mcSHLANG, SetServiceStatus и все связанное с этим вообще ни к чему. Почитайте статью, все это делается намного проще. Сломаться может как раз из-за этого, т.к. если сервису туда-сюда статусы рандомно менять, что-нибудь может отвалиться.

Еще стоит посмотреть, от кого запущен процесс. Возможно проблемы с правами, нужно в таких случаях либо логи писать, либо под дебаггером сидеть.

Добавлено через 6 минут
ну и да, FileSystemWatcher должен быть полем класса, иначе сборщик его убьет и на этом его славная работа закончится.

Добавлено через 1 минуту
Таймер тоже бесполезный. Если сервис запущен, и так понятно, что он работает. Лучше пишите в лог, когда файл обрабатываете, что типа "такой-то файл пытаюсь обработать". Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); вообще ни к чему, у сервиса нет потока вывода, только логи.

Добавлено через 1 минуту
Ну и лично мое мнение, что бэкап должен сохранять имя оригинального файла, а не затирать его меткой времени
1
5 / 5 / 2
Регистрация: 04.04.2013
Сообщений: 44
01.06.2016, 23:28  [ТС] 3
Psilon, благодарю.
Залогировал все действия, и сразу все стало понятно. Дело было в имени для нового файла, но предварительно удалил SetServiceStatus.

Может быть кому пригодиться, рабочий вариант:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public partial class MyNewService : ServiceBase
    {
        FileSystemWatcher watcher;
        public MyNewService(/*string[] args*/)
        {
            InitializeComponent();
            
            eventLog1 = new System.Diagnostics.EventLog();
 
 
            if (!System.Diagnostics.EventLog.SourceExists("MySource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog");
            }
 
            eventLog1.Source = "MySource";
            eventLog1.Log = "MyNewLog";
        }
 
        protected override void OnStart(string[] args)
        {
            // настраивается отслеживание
            watcher = new FileSystemWatcher();
            watcher.Path = "D:\\watcher";
            /* Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories. */
            watcher.NotifyFilter = NotifyFilters.LastWrite;
 
            // Only watch text files.
            watcher.Filter = "1.txt";
            //watcher.Filter = fileName;
 
            // Add event handlers.
            watcher.Changed += new FileSystemEventHandler(OnChanged);
 
            // Begin watching.
            watcher.EnableRaisingEvents = true;
 
            eventLog1.WriteEntry("In OnStart");
        }
 
 
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            // при обновлении даты
            try
            {
                FileInfo fi = new System.IO.FileInfo(e.FullPath);
                fi.CopyTo("D:\\watcher\\backup.txt", true);
                eventLog1.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.GetType().ToString() + ": " + ex.Message + " " + e.FullPath);
            }
        }
 
        protected override void OnStop()
        {
            eventLog1.WriteEntry("In onStop.");
        }
 
        protected override void OnContinue()
        {
            eventLog1.WriteEntry("In OnContinue.");
        }
    }
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
01.06.2016, 23:47 4
mcSHLANG, все связанное с инициализацией лучше в конструктор убрать. А то у вас после 3 перезапусков сервиса каждый файл будет по 3 раза копироваться. Вы ведь подписываетесь на событие, а отписки никакой нет. Если это происходит один раз, то ничего страшного, а вот то что это в onstart происходит плохо.
0
5 / 5 / 2
Регистрация: 04.04.2013
Сообщений: 44
26.07.2016, 14:24  [ТС] 5
Psilon, благодарю.
Залогировал все действия, и сразу все стало понятно. Дело было в имени для нового файла, но предварительно удалил SetServiceStatus.

Может быть кому пригодиться, рабочий вариант:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
public partial class MyNewService : ServiceBase
    {
        FileSystemWatcher watcher;
        public MyNewService(/*string[] args*/)
        {
            InitializeComponent();
            
            eventLog1 = new System.Diagnostics.EventLog();
 
 
            if (!System.Diagnostics.EventLog.SourceExists("MySource"))
            {
                System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog");
            }
 
            eventLog1.Source = "MySource";
            eventLog1.Log = "MyNewLog";
        }
 
        protected override void OnStart(string[] args)
        {
            // настраивается отслеживание
            watcher = new FileSystemWatcher();
            watcher.Path = "D:\\watcher";
            watcher.NotifyFilter = NotifyFilters.LastWrite;
 
            watcher.Filter = "*.*";
 
            // Add event handlers.
            watcher.Changed += new FileSystemEventHandler(OnChanged);
 
            // Begin watching.
            watcher.EnableRaisingEvents = true;
 
            flag = true;
            
            eventLog1.WriteEntry("In OnStart");
        }
 
        static DateTime creatTimeFile;
        static bool flag;
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            // при обновлении даты
            try
            {
                FileInfo fi = new System.IO.FileInfo(e.FullPath);
                if (flag)
                //FileInfo fin = new FileInfo("D:\\backup.txt");
                //if (fi.CreationTime!=fin.CreationTime)
                {
                    fi.CopyTo("D:\\backup.txt", true);
                    flag = false;
                    eventLog1.WriteEntry("File: " + e.FullPath + " " + e.ChangeType);
                }
            
                else
                {
                    flag = true;
                    eventLog1.WriteEntry("Повторный вызов");
                }
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(ex.GetType().ToString() + ": " + ex.Message + " " + e.FullPath);
            }
        }
        public bool CheckIfFileIsBeingUsed(string fileName)
        {
            try
            {
                File.Open(fileName, FileMode.Open, FileAccess.Write, FileShare.None);
            }
 
            catch (Exception exp)
            {
                return true;
            }
            return false;
        }
        protected override void OnStop()
        {
            eventLog1.WriteEntry("In onStop.");
            watcher.EnableRaisingEvents = false;
        }
 
        protected override void OnContinue()
        {
            eventLog1.WriteEntry("In OnContinue.");
            watcher.EnableRaisingEvents = true;
        }
    }
Единственное, почему то недоступна пауза для службы.
0
Эксперт .NET
6452 / 4053 / 1599
Регистрация: 09.05.2015
Сообщений: 9,487
26.07.2016, 14:29 6
Цитата Сообщение от mcSHLANG Посмотреть сообщение
Единственное, почему то недоступна пауза для службы.
ServiceBase.CanPauseAndContinue Property
0
26.07.2016, 14:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.07.2016, 14:29
Помогаю со студенческими работами здесь

Ошибка при передаче файла по FTP "Недопустимое имя файла"
Пытаюсь создать и отправить txt файл через ftp. Вот на форуме нашёл код: private void...

В чем ошибка при перезаписи файла?
есть файл в нем несколько строк такого вида 4|Новиков|Маким|Владимирович|россия|13к35|4 мая 2013...

Учитывать пробелы и табуляции при перезаписи файла
Добрый день, такое задание - есть файл с текстом и файл со словарем, нужно файл с тестом...

Избавление от перезаписи файла при запуске программы
Делаю программу с файлами. Задача - при первом запуске программы (как только появится форма)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru