это мой первый ТАК вопрос, поэтому я с нетерпением жду обратной связи в любом виде.
Что я пытаюсь сделать: Вкл. Windows Выйти / Выключить Я хочу изящно завершить работу java приложения (java приложение) Я запустил приложение Launcher (приложение Launcher, c#). Изящно означает, что в этом случае мне нужно сохранить текущее состояние в БД № SQL, используя вызов webAPI.
Что у меня есть: У меня есть Launcher Приложение C#, которое запускает клиент C# и два приложения java. Приложение Launcher хранит pids запущенных приложений java. Обычно программа закрывается записью системного трея, которая запускает вызов webAPI (для сохранения состояния в БД), а затем запускает taskkill с сохраненным pid.
Мне удалось поймать Logout с SessionEndedEventHandler
, здесь я запускаю webAPI для сохранения состояния.
Приложения были запрограммированы внешней компанией, но я должен осуществить это изящное завершение работы. У меня есть полный исходный код.
Проблема: При каждом запуске сохранения webAPI я получаю сообщение об ошибке:
One or more errors occurred.
[править] Если я вызываю taskkill в SessionEndedEvent появляется сообщение об ошибке (на экране выхода из системы), что таскилл не может быть вызван.
Мне кажется, что java приложения не запускаются как дочерние / подчиненные процессы. Поэтому я подозреваю, что приложения java будут убиты, прежде чем я смогу сохранить текущее состояние.
Как я могу убедиться, что я отправляю вызов webApi до того, как приложения java будут убиты. Что мне не хватает?
Заранее большое спасибо! Vlad
Некоторый код: Класс Programm
создает Launcher
, который запускает клиент c# и java приложения через класс ProcessExecutor
, который хранит пид, чтобы безопасно убить его позже. Таким образом, программа запуска содержит список ProcessExecutors.
Программа:
internal static class Program
{
private static Launcher launcher_;
[STAThread]
private static void Main(string[] args)
{
launcher_ = new Launcher(inSilentMode(args));
SystemEvents.SessionEnded += new SessionEndedEventHandler(SystemShutdownd);
Application.AddMessageFilter(new ShutdownFilter(launcher_));
using (NotifyIcon icon = new NotifyIcon())
{
icon.Icon = Resource.lec_mcheck_rgb_256px;
icon.ContextMenu = new ContextMenu(createMenuItems(launcher_));
icon.Visible = true;
icon.Text = "Launcher";
launcher_.launch();
Application.Run();
icon.Visible = false;
}
}
private static void SystemShutdownd(object sender, EventArgs e)
{
Log.info(System.DateTime.Now + " | SeassonEnded\n");
launcher_.fireServiceSave();
}
Панель запуска:
internal class Launcher
{
private void startServices(DirectoryInfo installationDir)
{
foreach (var folder in installationDir.GetDirectories())
{
DirectoryInfo binFolder = folder.GetDirectories().FirstOrDefault((x) => x.Name.Equals("bin"));
if (binFolder != null)
{
FileInfo batFile = binFolder.GetFiles().FirstOrDefault((x) => x.Extension.Equals(".bat"));
if (batFile != null)
{
ProcessExecutor executor = ProcessExecutor.createHiddenProcess(batFile.Name, batFile.Directory.FullName);
executor.start();
this.executors.Add(executor);
}
}
}
}
internal void stop()
{
Log.info(System.DateTime.Now + " | stop\n");
fireMCheckServiceSave();
foreach (var executor in executors)
{
executor.stop();
}
this.client?.stop();
Application.Exit();
}
public void fireServiceSave()
{
Log.info(System.DateTime.Now + " | fireServiceSave\n");
using (var httpClient = new HttpClient())
{
try
{
httpClient.Timeout = TimeSpan.FromMinutes(1);
var task = httpClient.PostAsync(new Uri(string.Format("http://127.0.0.1:{0}/api/connector/activeConfig/save", "9700")), null);
task.Wait();
Log.info(System.DateTime.Now + " | " + task.Status + " | " +
task.Result + "\n");
}
catch (Exception ex)
{
Log.info(System.DateTime.Now + " | " + ex.Message + "\n");
}
}
}
}
ProcessExecutor:
internal class ProcessExecutor
{
private readonly ProcessStartInfo startInfo;
internal static ProcessExecutor createHiddenProcess(string programPath, string workingDirectory)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = programPath;
startInfo.Arguments = "";
startInfo.WorkingDirectory = workingDirectory;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
return new ProcessExecutor(startInfo);
}
public void killProcessAndChildren(Process p)
{
if (p != null)
{
Process killerP = new Process();
killerP.StartInfo.FileName = "taskkill.exe";
killerP.StartInfo.Arguments = "/PID " + p.Id + " /T /F";
killerP.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
killerP.Start();
killerP.WaitForExit();
}
}
}
Ссылки, которые я прочитал (может быть, не полностью понимаю) :