Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.93/30: Рейтинг темы: голосов - 30, средняя оценка - 4.93
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
.NET 4.x

Работа файлового менеджера и связанное с ним

09.04.2021, 18:58. Показов 7315. Ответов 66
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Тема создана в результате критики архитектуры приложения в теме Модальное Окно для выбора операции с файлами без зависаний при выполнении цикла.

И так. Я начал с нуля программу. Её основой файловый менеджер служит. И очень много вопросов.

Во 1 файловый менеджер должен много каких операций выполнять.
Во 2 ему также нужны доступ к данным параметров игры так сказать.

Предыдущий код:
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Linq;
 
namespace Eador_M_of_the_B_W_Launcher
{
    class FileManager
    {
        public enum StopOperation
        {
            sopRunGame,
            sopUncompressingStart,
            sopRunSavesEditor,
            sopCMD,
            sopRunProg
        }
 
        class ProgressInfo
        {
            public ProgressInfo(StopOperation stopOperation)
            {
                this.stopOperation = stopOperation;
            }
 
            public StopOperation stopOperation { get; set; }
            public bool? isStartGame { get; set; }
            public string FileName { get; set; }
            public int? Progress { get; set; }
            public string ErrorMsg { get; set; }
        }
 
        private readonly IProgress<ProgressInfo> progress;
 
        public delegate void EventOutFile(string file);
        public event EventOutFile OutFile;
 
        public delegate void EventProgress(int progress);
        public event EventProgress Progress;
 
        public delegate void EventStop(StopOperation stopOperation, bool isError = false, string error = "");
        public event EventStop Stop;
 
 
        public delegate void EventStartGame();
        public event EventStartGame StartGame;
 
        public FileManager()
        {
            progress = new Progress<ProgressInfo>(OnProgress);
        }
 
        private void OnProgress(ProgressInfo pInfo)
        {
            if (pInfo.isStartGame == true)
            {
                StartGame?.Invoke();
                return;
            }
 
            if (pInfo.FileName != null)
            {
                OutFile?.Invoke(pInfo.FileName);
                return;
            }
 
            if (pInfo.Progress != null && pInfo.Progress.HasValue)
            {
                Progress?.Invoke(pInfo.Progress.Value);
                return;
            }
 
            if (pInfo.ErrorMsg != null && pInfo.ErrorMsg.Length > 0)
                Stop?.Invoke(pInfo.stopOperation, true, pInfo.ErrorMsg);
            else
                Stop?.Invoke(pInfo.stopOperation);
        }
 
        public void UncompressingStart(string pathTrainer, string extSave = "*.map")
        {
            SGeneral.ReSaveFiles();
            new Thread(() =>
            {
                UncompressingDoWork(pathTrainer, SGeneral.saveFiles, extSave);
            }).Start();
        }
 
        public void UncompressingStart(string pathTrainer, List<FileInfo> saves, string extSave = "*.map")
        {
            new Thread(() => { UncompressingDoWork(pathTrainer, saves, extSave); }).Start();
        }
 
        private void UncompressingDoWork(string pathTrainer, IList<FileInfo> files, string extSave)
        {
            try
            {
                for (int i = 0; i < files.Count; i++)
                {
                    string file = files[i].FullName;
 
                    progress.Report(new ProgressInfo(StopOperation.sopUncompressingStart) { FileName = file });
 
                    Cmd(true, false, $"eador.exe \"{file}\"", pathTrainer);
                    var prc = Convert.ToInt32(Convert.ToSingle(i + 1) / Convert.ToSingle(files.Count) * 100);
 
                    progress.Report(new ProgressInfo(StopOperation.sopUncompressingStart) { Progress = prc });
                }
 
                progress.Report(new ProgressInfo(StopOperation.sopUncompressingStart));
            }
            catch (Exception ex)
            {
                progress.Report(new ProgressInfo(StopOperation.sopUncompressingStart) { ErrorMsg = ex.Message });
            }
        }
 
        public void RunGameEador()
        {
            new Thread(() =>
            {
                try
                {
                    var isSteamVersion = SGeneral.settings.fileNameGame.Contains("steamapps");
                    if (isSteamVersion)
                    {
                        Process.Start("steam://rungameid/232050");
                        List<Process> processes;
 
                        do
                        {
                            processes = Process.GetProcessesByName("launcher").ToList();
                        } while (processes.Count <= 0);
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame) { isStartGame = true });
 
                        processes.ForEach(x => 
                        {
                            x.WaitForExit();
                        });
 
                        Thread.Sleep(1500);
 
                        processes = Process.GetProcessesByName("eador_mbw").ToList();
                        if (processes.Count > 0)
                        {
                            processes.ForEach(x =>
                            {
                                x.WaitForExit();
                            });
                        }
 
                        processes.Clear();
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame));
                    }
                    else
                    {
                        StartGame.Invoke();
                        ProcessHelper.StartProcessAndWaitForAllChildrenToExit(SGeneral.settings.fileNameGame, "", Path.GetDirectoryName(SGeneral.settings.fileNameGame));
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame));
                    }
                }
                catch (Exception ex)
                {
                    progress.Report(new ProgressInfo(StopOperation.sopRunGame) { ErrorMsg = ex.Message });
                }
 
            }).Start();
        }
 
        public void RunSavesEditor(string fileNameSave = "")
        {
            new Thread(() =>
            {
                try
                {
                    if (!File.Exists(fileNameSave))
                        fileNameSave = SGeneral.settings.pathSaves + SGeneral.settings.saveOskolok;
                    Cmd(true, false, $"eador.exe \"{fileNameSave}\"", $@"{SGeneral.pathProg}\DATA\Trainer");
                    if (File.Exists($@"{SGeneral.pathProg}\DATA\Trainer\config.xml"))
                    {
                        File.SetAttributes($@"{SGeneral.pathProg}\DATA\Trainer\config.xml", FileAttributes.Normal);
                        File.Delete($@"{SGeneral.pathProg}\DATA\Trainer\config.xml");
                    }
                    string config = $"<?xml version=\"1.0\" ?>{Environment.NewLine}<eador_trainer_config>{Environment.NewLine}" +
                            $"\t<eador_save_file_path>{fileNameSave}</eador_save_file_path>{Environment.NewLine}</eador_trainer_config>";
                    File.WriteAllText($@"{SGeneral.pathProg}\DATA\Trainer\config.xml", config);
                    File.SetAttributes($@"{SGeneral.pathProg}\DATA\Trainer\config.xml", FileAttributes.ReadOnly);
 
                    Cmd(true, false, $"java -jar \"{SGeneral.pathProg}\\DATA\\Trainer\\EadorTrainer_1.2.1_compact.jar\"", $@"{SGeneral.pathProg}\DATA\Trainer");
 
                    progress.Report(new ProgressInfo(StopOperation.sopRunSavesEditor));
                }
                catch (Exception ex)
                {
                    progress.Report(new ProgressInfo(StopOperation.sopRunSavesEditor) { ErrorMsg = ex.Message });
                }
 
            }).Start();
        }
 
        public void Cmd(bool isWait, bool isTheread, string arguments, string workingDirectory = "")
        {
            if (isWait && isTheread)
            {
                new Thread(() =>
                {
                    try
                    {
                        Process.Start(new ProcessStartInfo { FileName = "cmd", Arguments = $"/c {arguments}", WorkingDirectory = workingDirectory, WindowStyle = ProcessWindowStyle.Hidden }).WaitForExit();
                        progress.Report(new ProgressInfo(StopOperation.sopCMD));
                    }
                    catch (Exception ex)
                    {
                        progress.Report(new ProgressInfo(StopOperation.sopCMD) { ErrorMsg = ex.Message });
                    }
                }).Start();
            }
            else if (isWait)
                Process.Start(new ProcessStartInfo { FileName = "cmd", Arguments = $"/c {arguments}", WorkingDirectory = workingDirectory, WindowStyle = ProcessWindowStyle.Hidden }).WaitForExit();
            else
                Process.Start(new ProcessStartInfo { FileName = "cmd", Arguments = $"/c {arguments}", WorkingDirectory = workingDirectory, WindowStyle = ProcessWindowStyle.Hidden });
        }
 
        public void RunProg(bool isWait, bool isTheread, string filename, string arguments = null, string workingDirectory = null)
        {
            if (!File.Exists(filename))
                return;
 
            if (isWait && isTheread)
            {
                new Thread(() =>
                {
                    try
                    {
                        ProcessHelper.StartProcessAndWaitForAllChildrenToExit(filename, arguments, workingDirectory);
                        progress.Report(new ProgressInfo(StopOperation.sopRunProg));
                    }
                    catch (Exception ex)
                    {
                        progress.Report(new ProgressInfo(StopOperation.sopRunProg) { ErrorMsg = ex.Message });
                    }
 
                }).Start();
            }
            else if (isWait)
                ProcessHelper.StartProcessAndWaitForAllChildrenToExit(filename, arguments);
            else
                Process.Start(new ProcessStartInfo { FileName = filename, Arguments = arguments, WorkingDirectory = workingDirectory });
        }
    }
}


Но мне он сам не нравится особо так как взаимодействие с таким классом довольно таки тяжелая.

И так. Сама реализация методов останется не изменным так как они исполняют именно то что нужно.
Но надо сделать так чтобы взаимодействия с файловым менеджером была легкой.
И от сюда проблемы у этого. Во 1 операции может выполнятся сразу несколько и паралельно.
Основной операцией служит распаковка сохранений. Другое дело что в этот момент может также выполнятся и запуск игры (Который блин ну очень долгий и разделен на 2 этапа (1 - Игра запускается. 2 - Игра запущена))
и запуск редактора (который имеет этап редактор запущен)
Основная проблема это отображение информации. Здесь я использую 1 класс и (наверное все же это ошибка)
Вот приоритет отображение информации:
1. Распаковка сохранений
2. Запуск игры или игра запущена
3. Информация о запущенных других процессов.
И от сюда вытекает то что у окна для этого всего 3 элемента.
1 Это отображения процента распаковки или загаловка о том что игра запускается или запущена.
2 Это полоска которая в 1 случае отображает процент распаковки в виде полоски а в остальных случаях используется просто как бегущий ползунок
3. Это текстовое поле но уже конкретно под распаковку.
И также Файловому менеджору нужны данные (Параметры) игры которые конечно хранятся в отдельном классе settings и вот тут тоже не понятно. Их конечно можно передать в методы но с другой стороны хотелось бы сами данные сделать глобальными чтобы сами методы смогли получить доступ к данным. Данные конечно нельзя хранить в файловом менеджере так как они использоваться будут не только там.

Добавлено через 9 минут
И так. Есть вариант разделить операции под отдельные классы тоесть запуск игры отдельный класс. Запуск редакторов отдельный. Распаковка отдельный и запуск файлов тоже отдельный и создавать отдельные объекты для каждой операции соотвественно описать события которые повторятся будут в интерфейсе но с другой стороны это весьма затратно по памяти к томуже это все равно не решает приоритетов выполнения отображения информации о выполнении операций. Сами операции должны выполнятся паралельно это важно.

Добавлено через 18 минут
И более подробно о каких данных идет речь:
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
namespace Eador_M_of_the_B_W_Launcher.DataModel.DATA
{
    public class DATAGame
    {
        /// <summary>
        /// Задать настройки по новой
        /// </summary>
        public bool ReSetDATAGame { get; set; }
 
        /// <summary>
        /// Файл с сохранением в Астрале
        /// </summary>
        public string FileNameSaveAstral { get; set; }
        /// <summary>
        /// Файл с сохранением на Осколке
        /// </summary>
        public string FileNameSaveOskolok { get; set; }
        /// <summary>
        /// Файл игры (Полный путь и имя файла)
        /// </summary>
        public string FullNameGame { get; set; }
        /// <summary>
        /// Папка с сохранениями
        /// </summary>
        public string SaveFolder  { get; set; }
        /// <summary>
        /// Файл hex редактора (Полный путь и имя файла)
        /// </summary>
        public string FullNameHexEditor { get; set; }
    }
}
Это модель данных с данными игры. Вот именно она и должна быть глобальной. Также объект этого класса будет серилизоваться и десерилизоваться в JSON
И список с сохранениями уже нужно создавать после того как данные загружены. Так как я говорил что данные эти и сам список должен быть глобальными то хранить объект с этими данными в cs окна отметаем. Но с друго йстороны где это вообще хранить. И вообще производить загрузка данных и запрос на данные если они отсуствуют.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.04.2021, 18:58
Ответы с готовыми решениями:

Шаблон файлового менеджера
Приветствую Уважаемые коллеги! Может есть у кого на примете шаблон файлового менеджера? Хочу что то похожее как в open cart. ...

Разработка файлового менеджера
Доброго времени суток, уважаемые форумчане! Есть файловый менеджер, работает копирование и перемещение файлов из каталогов, думал что этого...

Реализация файлового менеджера
Нужно сделать программу что-то вроде &quot;Файлового менеджера&quot;(Упрощённый, то есть отображение структуры файлов, функции такие как: копировать,...

66
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
11.04.2021, 21:32
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Вроде 4.7 последний NET Framework совместимый с Windows 7.
Вы на Win7 ?
WPF в некоторых деталях для Win7 имеет существенные отличия.
Некоторые решения требует принципиально разной реализации для Win7 и Win8.1+.

Добавлено через 45 секунд
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
С интерфейсом вообще думаю разбираться в последнюю очередь.
Да.
Я поэтому и писал, что отладки надо будет (чуть позже) добавить консольный проект.

Добавлено через 15 секунд
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Синхронизировался вроде если конечно студия это позволяет делать.
Позволяет.

Добавлено через 36 секунд
Я с Гитом только из Студии работаю.

Добавлено через 2 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
4.7 последний NET Framework совместимый с Windows 7.
Как я понял из этого https://docs.microsoft.com/ru-... -windows-7
4.8 тоже можно установить.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
11.04.2021, 22:19  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вы на Win7 ?
WPF в некоторых деталях для Win7 имеет существенные отличия.
Некоторые решения требует принципиально разной реализации для Win7 и Win8.1+.
Я на 10 но должна быть совместимость с 7 но да ладно. Не важно.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Да.
Я поэтому и писал, что отладки надо будет (чуть позже) добавить консольный проект.
Ну значит надо добавить еще и консольный проект потом просто удалить.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как я понял из этого https://docs.microsoft.com/ru-... -windows-7
4.8 тоже можно установить.
Ну оставить 4.8. Что дальше. Добавлю пожалуй класс серилизации данных игры.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
11.04.2021, 22:30
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Ну значит надо добавить еще и консольный проект потом просто удалить.
Да, потом добавим как до отладки дойдёт.
Удалять его е надо будет.
В WPF проекте не будет ссылки на него и он не попадёт в WPF сборку.

Добавлено через 36 секунд
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Ну оставить 4.8. Что дальше. Добавлю пожалуй класс серилизации данных игры.
Завтра напишу.
0
12.04.2021, 03:38

Не по теме:

Цитата Сообщение от Элд Хасп Посмотреть сообщение
WPF Core несколько отличается от WPF FW.
У меня смутные подозрения что до этих отличий вы не доберетесь в этом проекте....

0
Эксперт .NET
 Аватар для Usaga
14815 / 9589 / 1368
Регистрация: 21.01.2016
Сообщений: 36,114
12.04.2021, 05:51
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
должна быть совместимость с 7
Забудьте о семёрке. Хорошая была ОС, но она уже всё.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
12.04.2021, 09:20
Цитата Сообщение от Wolfdp Посмотреть сообщение
У меня смутные подозрения что до этих отличий вы не доберетесь в этом проекте....
Если случайно они вылезут - то придётся с ними разбираться.
Если же нет, то и разницы никакой не будет.
Так что смысла, в данном случае, акцентироваться на Core не вижу.

Добавлено через 5 минут
Alexandr_7, MainDataGame - это под что заготовка?

Добавлено через 14 минут
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
4.7 последний NET Framework совместимый с Windows 7.
Как я понял из этого https://docs.microsoft.com/ru-... -windows-7
4.8 тоже можно установить.
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
1. Запуск игры.
1. Запускаем игру (Если Steam версия то по ссылке steam://rungameid/232050)
2. Ждем когда игра запустится. Появление процесса launcher.exe (Вообще дебильное название. Название часто используемое просто. Вот и определяй а тот ли Лаунчер запустился (Хотя наверное можно по процессу определить его местонахождение в папке я думаю))
3. Говорим главному окну информацию о том что Лаунчер запущен.
4. Ждем покуда процесс launcher.exe не закроется.
5. Делаем паузу так как после закрытия launcher.exe игра (сама игра а не его launcher) открывается не сразу.
6. Проверяем наличия процесса eador_mbw (Если есть то говорим окну что игра запущена и ждем завершение прежде чем вызвать событие Стоп)
И подробнее по каждому пункту.
1) Запускаем игру. Что метод получает в параметрах и возвращает?

2) Как ждём? Тормозим поток метода запуска или асинхронно по запуску игры создаём событие?
Как именно определяется запуск игры - оставляем на ваше усмотрение. В это влазить я не буду.

3) "Говорим" - значит событие точно нужно. Что должно быть в параметрах события?

4) Опять "ждём" - синхронно, асинхронно?

5) Что за пауза, её длительность? Пауза синхронная, асинхронная?

6) Проверка - на ваше усмотрение. Если проверка положительная - создаём событие. А если отрицательная?

7) Одновременно может запускаться только одна игра? То есть если начат процесс запуска, то пока не будет остановки, метод запуска должен быть заблокирован?
Если да, то здесь требуется команда.

P.S. Можете сослаться в ответах уже реализованные методы в вашем предыдущем варианте.
0
12.04.2021, 10:09

Не по теме:

Цитата Сообщение от Usaga Посмотреть сообщение
Забудьте о семёрке.
Ага, скажи это людям, которые продают под неё софт.

0
12.04.2021, 10:18

Не по теме:

Wolfdp, при первой же встрече)

0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
12.04.2021, 14:47  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Alexandr_7, MainDataGame - это под что заготовка?
Это студия создавала этот класс и по сути это основной класс библиотеки.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
И подробнее по каждому пункту.
1) Запускаем игру. Что метод получает в параметрах и возвращает?
Этот метод создает отдельный поток и выполняет код в отдельном потоке. Возвращать должен несколько вещей.
1. Это когда запущен лаунчер. (Возвращает строку о том что Лаунчер запущен)
2. Возвращает строку о том что ожидает запуск игры.
3. Возвращает строку что игра запущена (Если конеечсно пользователь ее всеже запустил так как открытие лаунчера не гарантирует что игра будет запущена)
4. Возвращает факт того что поток окончил свою работу.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
2) Как ждём? Тормозим поток метода запуска или асинхронно по запуску игры создаём событие?
Как именно определяется запуск игры - оставляем на ваше усмотрение. В это влазить я не буду.
Я так определяю:
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
public void RunGameEador()
        {
            new Thread(() =>
            {
                try
                {
                    var isSteamVersion = SGeneral.settings.fileNameGame.Contains("steamapps");
                    if (isSteamVersion)
                    {
                        Process.Start("steam://rungameid/232050");
                        List<Process> processes;
 
                        do
                        {
                            processes = Process.GetProcessesByName("launcher").ToList();
                        } while (processes.Count <= 0);
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame) { isStartGame = true });
 
                        processes.ForEach(x => 
                        {
                            x.WaitForExit();
                        });
 
                        Thread.Sleep(1500);
 
                        processes = Process.GetProcessesByName("eador_mbw").ToList();
                        if (processes.Count > 0)
                        {
                            processes.ForEach(x =>
                            {
                                x.WaitForExit();
                            });
                        }
 
                        processes.Clear();
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame));
                    }
                    else
                    {
                        StartGame.Invoke();
                        ProcessHelper.StartProcessAndWaitForAllChildrenToExit(SGeneral.settings.fileNameGame, "", Path.GetDirectoryName(SGeneral.settings.fileNameGame));
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame));
                    }
                }
                catch (Exception ex)
                {
                    progress.Report(new ProgressInfo(StopOperation.sopRunGame) { ErrorMsg = ex.Message });
                }
 
            }).Start();
        }
В данном случае важно это:
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
Process.Start("steam://rungameid/232050");
                        List<Process> processes;
 
                        do
                        {
                            processes = Process.GetProcessesByName("launcher").ToList();
                        } while (processes.Count <= 0);
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame) { isStartGame = true });
 
                        processes.ForEach(x => 
                        {
                            x.WaitForExit();
                        });
 
                        Thread.Sleep(1500);
 
                        processes = Process.GetProcessesByName("eador_mbw").ToList();
                        if (processes.Count > 0)
                        {
                            processes.ForEach(x =>
                            {
                                x.WaitForExit();
                            });
                        }
 
                        processes.Clear();
 
                        progress.Report(new ProgressInfo(StopOperation.sopRunGame));
Код конечно нужно менять но думаю суть ясна.
Но вообще для начала нужно бы тогда разобраться с получением данных игры.
Так как файлавому менеджеру нужны данные. Файловому менеджуру нужно знать 2 параметра.
Методу важно знать несколько вещей полное имя файла запускаем игры и проверку является ли игра Стим версией.
Всеже запуск стим версии и обычной сильно различаются. Хотя в целом похожи. Так как будь то обычная игра в любом случае запускается 1 Лаунчер игры.

Добавлено через 55 секунд
Цитата Сообщение от Элд Хасп Посмотреть сообщение
7) Одновременно может запускаться только одна игра? То есть если начат процесс запуска, то пока не будет остановки, метод запуска должен быть заблокирован?
Если да, то здесь требуется команда.
Игра и Лаунчер может быть запущены в 1 экземпляре естественно.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
12.04.2021, 18:07
Отслеживание запуска сторонего процесса по идеи можно отслеживать через ManagementEventWatcher, но там вроде права админа нужны...
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
14.04.2021, 08:05  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
P.S. Можете сослаться в ответах уже реализованные методы в вашем предыдущем варианте
Не понял. Но там старый код нужно менять. Сначало нужно реализовать загрузку данных игры. Это в классе MainDataGame.

Думаю на 3 библиотеки прийдется делить.

1. DATAGameLibrary - Отвечает за получения и хранения данных игры (Ну это файл игры, файлы сохранений и прочие)
2. FileManagerGameLibrary - Отвечает за работу с файлами игры
3. MessageServiceLibrary - Обертка над MessageBox + свои диалоговые окна.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
14.04.2021, 21:10
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Думаю на 3 библиотеки прийдется делить.
Почему прям библиотеки? Больше смахивает на три отдельных класса со своими обязаностями.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
14.04.2021, 21:26
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Сначала нужно реализовать загрузку данных игры.
Откуда?
Как это всё хранится?
В какие типы всё это надо парсить?

Добавлено через 1 минуту
Цитата Сообщение от Wolfdp Посмотреть сообщение
Почему прям библиотеки? Больше смахивает на три отдельных класса со своими обязаностями.
Ну, как минимум третий пункт лежит перпендикулярно к первым двум.
И он должен быть в отельной от них сборке.

Добавлено через 2 минуты
Alexandr_7, я извиняюсь за поздние ответы - просто навалилась своя груда неразобранных дел.
На что-то простое могу с ходу с телефона отвечать.
Но ваша тема требует серьёзного отношения и вникания.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
15.04.2021, 01:04  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Откуда?
Как это всё хранится?
В какие типы всё это надо парсить?
Парсинг в JSON да в принципе вот код парсинга туда и обратно:

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
105
106
107
108
private bool SaveDATAGame(string _filename)
        {
            File.WriteAllText(_filename, JsonSerializer.Serialize(dataGame, new JsonSerializerOptions { WriteIndented = true, IgnoreNullValues = true }));
            return true;
        }
private bool LoadDATAGame(string _filename)
        {
            if (File.Exists(_filename))
            {
                dataGame = JsonSerializer.Deserialize<DATAGame>(File.ReadAllText(_filename), new JsonSerializerOptions { IgnoreNullValues = true });
 
                if (dataGame.ReSetDATAGame)
                    SetDATAGame();
 
                return true;
            }
            else
                return SetDATAGame();
        }
private bool SetDATAGame()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Multiselect = false,
                ValidateNames = true,
                CheckFileExists = true,
                CheckPathExists = true,
                DereferenceLinks = true,
            };
 
            openFileDialog.Filter = "launcher.exe|launcher.exe";
            openFileDialog.DefaultExt = "launcher.exe";
            openFileDialog.Title = "Выберите launcher.exe в папке с игрой";
 
            if (openFileDialog.ShowDialog() == true)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FullNameGame = openFileDialog.FileName;
                else
                    return false;
            }
            else
            {
                return false;
            }
 
            var betterFolderBrowser = new BetterFolderBrowser
            {
                Multiselect = false,
                RootFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "Выберите папку с сохранениями"
            };
 
            if (betterFolderBrowser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (Directory.Exists(betterFolderBrowser.SelectedFolder))
                    dataGame.SaveFolder = betterFolderBrowser.SelectedFolder;
                else
                    return false;
            }
            else
            {
                return false;
            }
 
            openFileDialog.Filter = "Сохранение(*.map)|*.map";
            openFileDialog.DefaultExt = "*.map";
            openFileDialog.Title = "Выберите постоянное сохранение с данными осколка";
            openFileDialog.InitialDirectory = dataGame.SaveFolder;
 
            if (openFileDialog.ShowDialog() == true)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FileNameSaveOskolok = $@"\{Path.GetFileName(openFileDialog.FileName)}";
                else
                    dataGame.FileNameSaveOskolok = "";
            }
            else
                dataGame.FileNameSaveOskolok = "";
 
            openFileDialog.Title = "Выберите постоянное сохранение с данными Астрала";
 
            if (openFileDialog.ShowDialog() == true)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FileNameSaveAstral = $@"\{Path.GetFileName(openFileDialog.FileName)}";
                else
                    dataGame.FileNameSaveAstral = "";
            }
            else
                dataGame.FileNameSaveAstral = "";
 
            openFileDialog.Filter = "HEX Редактор(*.exe)|*.exe";
            openFileDialog.DefaultExt = "*.exe";
            openFileDialog.Title = "Выберите hex редактор для редактирование сохранений вручную";
 
            if (openFileDialog.ShowDialog() == true)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FullNameHexEditor = openFileDialog.FileName;
                else
                    dataGame.FullNameHexEditor = null;
            }
 
            dataGame.ReSetDATAGame = false;
 
            return SaveDATAGame(Directory.GetCurrentDirectory() + fileName);
        }
Ну это старый код. Еще переделаю. Но я не знаю стоит ли выносить в интерфейс. Всеже они используются конкретно в этом классе и нигде больше.

Цитата Сообщение от Wolfdp Посмотреть сообщение
Почему прям библиотеки? Больше смахивает на три отдельных класса со своими обязаностями.
Ну например в Данных игры класса не 1 а 2. В сервисе сообщений класс 1 и 1 интерфейс. Просто мне Сама библиотека сервис сообщений может пригодится и в других приложениях. А объеденять Данные игры и файловый менеджер я не хочу. Да файловому менеджеру нужно будет знать данные игры. Думаю передавать не целиком все данные а по необходимости. Так что интерфейс данных игры передавать файловому менеджеру не стану. Со списком сохранений нужно еще разобраться так как списки должны находится в библиотеки данных игры но к ним доступ должны иметь как и файловый менеджер так и модульное окно выбора операций проводимых с сохранениями.

2 списка. 1 со всеми файлами. Второй с выбранными (кокрас через диалоговое окно)

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Alexandr_7, я извиняюсь за поздние ответы - просто навалилась своя груда неразобранных дел.
На что-то простое могу с ходу с телефона отвечать.
Но ваша тема требует серьёзного отношения и вникания.
Не беда. Я обновил проект. Можешь посмотреть и подправить если где не прав.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
16.04.2021, 16:49  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Alexandr_7, я извиняюсь за поздние ответы - просто навалилась своя груда неразобранных дел.
На что-то простое могу с ходу с телефона отвечать.
Но ваша тема требует серьёзного отношения и вникания.
Чет не прокомментировали никак код что написал.
Вот:
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
using DATAGame_Library.DATA;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using WK.Libraries.BetterFolderBrowserNS;
using MessageService_Library;
 
 
namespace DATAGame_Library
{
    public interface IMainDataGame
    {
        //Данные игры
        DATAGame DATAGame { get; set; }
 
        //Проверка на (Является ли игра Steam версией)
        bool IsGameSteam { get; }
        //Проверка на наличия файла сохранения Астрала (Если выбран файл по умолчанию)
        bool IsFileNameSaveAstral { get; }
        //Проверка на наличия файла сохранения Осколка (Если выбран файл по умолчанию)
        bool IsFileNameSaveOskolok { get; }
    }
 
    public class MainDataGame : IMainDataGame
    {
        /// <summary>
        /// Имя файла сохранения / загрузки данных игры
        /// </summary>
        private const string fileNameDATAGame = @"\DataGame.json";
 
        /// <summary>
        /// Интерфейс сервиса сообщений
        /// </summary>
        private readonly IMessageService _messageService;
 
        /// <summary>
        /// Данные игры
        /// </summary>
        public DATAGame dataGame = new DATAGame();
 
 
 
        public MainDataGame(IMessageService _messageService)
        {
            this._messageService = _messageService;
 
            try
            {
                if (!LoadDATAGame(Environment.CurrentDirectory + fileNameDATAGame))
                    throw new Exception($"Необходимые данные небыли загружены!{Environment.NewLine}Программа будет закрыта!");
            }
            catch (Exception ex)
            {
                _messageService.MessageError(ex.Message, "Ошибка загрузки данных");
                Environment.Exit(0);
            }
        }
 
        #region Загрузка данных
 
        private bool LoadDATAGame(string _filename)
        {
            if (File.Exists(_filename))
            {
                dataGame = JsonSerializer.Deserialize<DATAGame>(File.ReadAllText(_filename), new JsonSerializerOptions { IgnoreNullValues = true });
 
                if (dataGame.IsSetDATAGame)
                    SetDATAGame();
 
                return true;
            }
            else
                return SetDATAGame();
        }
 
        #endregion
 
        #region Получения данных от пользователя
 
        private bool SetDATAGame()
        {
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Multiselect = false,
                ValidateNames = true,
                CheckFileExists = true,
                CheckPathExists = true,
                DereferenceLinks = true,
            };
 
            openFileDialog.Filter = "launcher.exe|launcher.exe";
            openFileDialog.DefaultExt = "launcher.exe";
            openFileDialog.Title = "Выберите launcher.exe в папке с игрой";
 
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FullNameGame = openFileDialog.FileName;
                else
                    return false;
            }
            else
            {
                return false;
            }
 
            var betterFolderBrowser = new BetterFolderBrowser
            {
                Multiselect = false,
                RootFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
                Title = "Выберите папку с сохранениями"
            };
 
            if (betterFolderBrowser.ShowDialog() == DialogResult.OK)
            {
                if (Directory.Exists(betterFolderBrowser.SelectedFolder))
                    dataGame.SaveFolder = betterFolderBrowser.SelectedFolder;
                else
                    return false;
            }
            else
            {
                return false;
            }
 
            openFileDialog.Filter = "Сохранение(*.map)|*.map";
            openFileDialog.DefaultExt = "*.map";
            openFileDialog.Title = "Выберите постоянное сохранение с данными осколка";
            openFileDialog.InitialDirectory = dataGame.SaveFolder;
 
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FileNameSaveOskolok = $@"\{Path.GetFileName(openFileDialog.FileName)}";
                else
                    dataGame.FileNameSaveOskolok = "";
            }
            else
                dataGame.FileNameSaveOskolok = "";
 
            openFileDialog.Title = "Выберите постоянное сохранение с данными Астрала";
 
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FileNameSaveAstral = $@"\{Path.GetFileName(openFileDialog.FileName)}";
                else
                    dataGame.FileNameSaveAstral = "";
            }
            else
                dataGame.FileNameSaveAstral = "";
 
            openFileDialog.Filter = "HEX Редактор(*.exe)|*.exe";
            openFileDialog.DefaultExt = "*.exe";
            openFileDialog.Title = "Выберите hex редактор для редактирование сохранений вручную";
 
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(openFileDialog.FileName))
                    dataGame.FullNameHexEditor = openFileDialog.FileName;
                else
                    dataGame.FullNameHexEditor = null;
            }
 
            dataGame.IsSetDATAGame = false;
 
            SaveDATAGame(Directory.GetCurrentDirectory() + fileNameDATAGame);
 
            return true;
        }
 
        #endregion
 
        #region Сохранение данных
 
        private void SaveDATAGame(string _filename)
        {
            File.WriteAllText(_filename, JsonSerializer.Serialize(dataGame, new JsonSerializerOptions { WriteIndented = true, IgnoreNullValues = true }));
        }
 
        #endregion
 
        #region Свойства
 
        public DATAGame DATAGame { get => dataGame; set => dataGame = value; }
 
        public bool IsGameSteam => dataGame.FullNameGame.Contains("steamapps");
 
        public bool IsFileNameSaveAstral => File.Exists(dataGame.SaveFolder + dataGame.FileNameSaveAstral);
 
        public bool IsFileNameSaveOskolok => File.Exists(dataGame.SaveFolder + dataGame.FileNameSaveOskolok);
 
        #endregion
    }
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
17.04.2021, 02:12
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
openFileDialog.
раз уж пошли писать либу, то никаких диалоговых окон. Получайте на вход путь к файлу, либо как с messageBox выносите в сервис. Вообще не добавляйте System.Windows и прочее

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Environment.Exit(0);
и я вроде уже писал что глушить ошибки в конструкторе не самая лучшая практика. Ваш класс не должен знать где он будет вызыватся.
0
 Аватар для Alexandr_7
87 / 22 / 6
Регистрация: 29.12.2015
Сообщений: 1,904
17.04.2021, 21:37  [ТС]
Цитата Сообщение от Wolfdp Посмотреть сообщение
и я вроде уже писал что глушить ошибки в конструкторе не самая лучшая практика. Ваш класс не должен знать где он будет вызыватся.
Ну вообще мне по факту нужно закрыть программу если данные не будут загружены. Если можно переделать конструктор на возврат значения то тогда уже можно и убрать Environment.Exit(0); и вынести именно туда где будет происходить само создание биьлиотеки. в WinForms бы подошел Programs.cs но в wpf прийдется через app.xaml

Цитата Сообщение от Wolfdp Посмотреть сообщение
раз уж пошли писать либу, то никаких диалоговых окон. Получайте на вход путь к файлу, либо как с messageBox выносите в сервис. Вообще не добавляйте System.Windows и прочее
И где я вам должен описывать вызов диалогов для выбора необходимых путей. В главном окне. Это немного тупо учитывая что полученные данные нужно хранить именно в этой библиотеке. И загружать их естественно в этой библиотеке.

Так. Я в ступор пришел. Я вообще не понимаю как тогда сделать через MVP
И так:
Нужно загрузить данные из json (но если файл отсуствет нужно их задать (Если ни загрузить и ни задать не получилось то нужно закрыть программу а значит библиотека должна возвращать истину или ложь. А вот тут реально проблема так как конструкторы не умеют возвращать значение. Можно обойти возвращая значение в параметр конструктора или через событие но я не знаю как еще можно вернуть значение через конструктор класса. А создавть отдельный метод который прийдется отдельно вызывать не в библиотеки я не хочу. Это неправильно)) Но да. То что из библиотеки нужно убирать Environment.Exit(0); это факт.

Добавлено через 4 минуты
Вообще через событие было бы наверное отличным вариантом так как в событие тогда можно будет выдовать любые ошибки и уже окно их будет отображать. Другой вопрос как передать метод для событие MainDataGame
Через параметр конструктора в идеале но я не совсем в курсе как это оформить.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
18.04.2021, 08:13
Сделайте хотя бы так...

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Library
using System;
using System.Threading.Tasks;
 
public class GamePathsModel
{
    public string Astral { get; set; }
 
    public string Oskolok { get; set; }
 
    public string Game { get; set; }
 
    public string Save { get; set; }
 
    public string HexEditor { get; set; }
}
 
public interface IGamePathsProvider
{ 
    GamePathsModel Model { get; }
}
 
public class FileManager
{
    private readonly IGamePathsProvider _pathProvider;
    private readonly IMessageService _messageService
 
    public FileManager(IGamePathsProvider pathProvider, IMessageService messageService)
    {
        _pathProvider = pathProvider;
        _messageService = messageService;
    }
 
    public Task UncompressingStart()
    {
        var pathsModel = _pathProvider.Model;
 
        // дальше ваша реализация запуска чего там нужно.
        throw new NotImplementedException();
    }
}
 
// Launcher
using System;
using System.Windows;
using System.IO;
 
public interface IGamePathDialog 
{
    void SetPathsDialog();
}
 
public interface IGamePathLoader //напрашивается вынесте в Library
{
    void LoadFromFile(string path);
}
 
public class GamePaths : 
    //целых три интерфейса намекают что логику можно и разнести, но можно сделать и в дальнейшем
    IGamePathsProvider, 
    IGamePathDialog,
    IGamePathLoader
{
    private GamePathsModel model;
 
    public GamePathsModel Model => model;
 
    public GamePaths()
    {
    }
 
    public GamePaths(string path)
    {
        LoadPaths(string path);
    }
 
    public void LoadFromFile(string path)
    {
        var data = File.ReadAllText(path);
        model = data.ParseToModel();
    }
 
    public bool SetPathsDialog()
    {
        model = new GamePathsModel()
        var dialogWindow = new DialogWindow(model); //ну либо 100500 OpenFileDialog, я бы все же набрал окно где можно задать все параметры сразу
        var dialogResult = dialogWindow.ShowDialog();
        if (dialogResult)
            model = dialogWindow.Model;
        return dialogResult;
    }
}
 
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (Init())
            new MainWindow().Show();
        else
            Shutdown();
    }
 
    private bool Init()
    {
        try
        {
            #region в идеале все это нужно запихнуть в контейнер, например Unity
            var messageService = new MessageService();
            var gamePath = new GamePaths();
            var fileManager = new FileManager(gamePath, messageService);
            var mainWindow = new MainWindow(fileManager);
            #endregion
 
            #region пытаемся считать настройки или просим пользователя их ввести
            try
            {
                gamePath.LoadFromFile("setting.file");
            }
            catch (Exception ex)
            {
                messageService.Show(ex);
                if (!gamePath.SetPathsDialog())
                    return;
            }
            #endregion
 
            mainWindow.Show();
            return true;
        }
        catch
        {
            return false;
        }
    }
}
 
public class MainWindow : Window
{
    FileManager _fileManager;
    IGamePathDialog _gamePathDialog
 
    public MainWindow(FileManager fileManager, IGamePathDialog gamePathDialog)
    {
        _fileManager = fileManager;
        _gamePathDialog = gamePathDialog;
    }
 
    private void SetPathsDialogButton_Click() => _gamePathDialog.SetPathsDialog();
 
    private void UncompressingStartButton_Click() => _fileManager.UncompressingStart()
}
Понятное дело что все эти SetPathsDialogButton_Click не особо соответствуют патерну MVVM, но это исключительно для демонстрации что дальше в главном окне вы просто работаете с FileManager, а если нужно в рантайме поменять настройки папок -- можно легко сменить через провайдера.

Добавлено через 2 минуты
Ну и да, я думаю Элд Хасп сможет более "адекватно" раписать как нужно биндить менеджер к форме, но лично мое мнение: если не знаете MVVM на уровне мастера, можно спокойно работать по старинке через event, проект не выглядить мегасложным для этого.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,177
Записей в блоге: 2
19.04.2021, 17:42
Цитата Сообщение от Wolfdp Посмотреть сообщение
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
openFileDialog
раз уж пошли писать либу, то никаких диалоговых окон.
Ну, не так жёстко....
MessageBox - диалоговое окно и находится в библиотеке.
Почему бы не сделать своё кастомное аналогичное?

Цитата Сообщение от Wolfdp Посмотреть сообщение
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Environment.Exit(0);
я вроде уже писал что глушить ошибки в конструкторе не самая лучшая практика
С этим согласен.

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Я в ступор пришел. Я вообще не понимаю как тогда сделать через MVP
Дело не в паттернах.
Возьмите для примера MessageBox.
Вы обращаетесь к его СТАТИЧЕСКОМУ методу, который возвращает РЕЗУЛЬТАТ ДИАЛОГА.

Так же и вам следует поступить.
Конструкторы экземпляров надо инкапсулировать.
Добавить статический метод получающий в параметрах нужные значения: имя и расположение файла, ссылки на сервисы, контейнер для возврата полученных данных и др.
А возвращает метод результат выполнения диалога: успешно, ошибка и др.

Добавлено через 2 минуты
Диалог этот будет вызываться в App.Startup и по его результату App будет принимать решение о продолжение работы или завершении с ошибкой.

Добавлено через 2 минуты
Цитата Сообщение от Wolfdp Посмотреть сообщение
но лично мое мнение: если не знаете MVVM на уровне мастера
....?
Это же простейший шаблон.
Какие здесь ещё есть уровни?

Он даже проще в реализации чем MVC и MVP.
0
Эксперт .NET
 Аватар для Wolfdp
3790 / 1767 / 371
Регистрация: 15.06.2012
Сообщений: 6,543
Записей в блоге: 3
19.04.2021, 19:51
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ну, не так жёстко....
Не стоит путать либу с логикой приложения, и либу с компонентами формы. Если уж взялись выносить логику, то она не должна знать что данные будут вводится пользователем через OpenFileDialog, а тупо принимать на вход path. Иначе зачем вообще все эти телодвижения?

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Какие здесь ещё есть уровни?
Я не про уровни, а что можно не выносить мозг на старте биндингом данных и команд. Хотя переделывать потом будет весело.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.04.2021, 19:51

Исходник файлового менеджера
Есть ли у кого нибудь исходник файлового менеджера(проводника) на C# в visual studio 2012 -2017

Оформление для файлового менеджера
Глупо задавать вопрос. Но сам я затрудняюсь красиво оформить вкладку графиеских файлов чтобы все влезло Вот это окно где уже лежать...

Основные функции файлового менеджера
Добрый день. Имеется начальный вид файлового менеджера (отображение структуры дисков, переходы по папкам, упорядоченные столбцы (имя,...

Каково устройство файлового менеджера?
Доброго времени суток. хочу сделать простенький файловый менеджер, что бы он мог выполнять простейшие функции, например: удаление,...

Смена файлового менеджера по умолчанию
Как сменить файловый менеджер по умолчанию на Linux mint 17 MATE? Надо чтобы все папки, включая computer:///, trash:///, домашнюю и т.д.,...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru