@your_mirror

Почему закрывается «дочерний» процесс консольного приложения?

Привет любителя Mono и не любителям :)

Немного о системе:
Linux dev 3.2.0-4-686-pae #1 SMP Debian 3.2.41-2 i686 GNU/Linux
Mono JIT compiler version 4.2.1

На данном этапе я делаю апдейтер для программы, который запускает bash скрипт с некоторыми командами и я не могу понять принцип поведения процесса с консольным приложением или каким-либо другом (например xcalc).

Для примера.
У меня есть Game.exe GUI приложение, которое создает процесс, который запускает консольное приложение Update.exe. Если я закрываю приложение Game.exe, то Update.exe закрывается так же.

Если для примера, я открою вместо Update.exe, какой-нить xcalc, то xcalc так же закроется в случае закрытия Game.exe.

Вопросы:
1. Почему так происходит?
2. Как сделать, чтобы Update.exe не закрывался при закрытии Game.exe?
  • Вопрос задан
  • 684 просмотра
Решения вопроса 1
@your_mirror Автор вопроса
Решил таким образом. Game.exe и Update.exe закроются, но останется открыта консоль из Update.exe и будет независимым процессом.

Melz, В Windows я делал обновление похожим образом, но там при закрытии Game.exe, Update.exe не являлся для него дочерним и существовал далее.

Код Game.exe:
static public void Run(Version version)
		{
			ProcessStartInfo psi = new ProcessStartInfo() {
				WorkingDirectory = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory),
				FileName = "/usr/bin/mono",
				Arguments = String.Format("Update.exe -exe \"{0}\" -ud \"{1}\" -v \"{2}\"", Process.GetCurrentProcess().ProcessName, Config.ServerUrl, version)
			};
			Process.Start(psi).WaitForExit();

			MainForm.Instance.Close();
		}


Код Update.exe:
public static int Main(string[] args)
		{
			ParseArguments(args);
			String tmpFile = Path.GetTempFileName();
			File.Copy("update.sh", tmpFile, true);
			Process.Start("xterm", String.Format("-e sudo bash {0} {1} {2} {3}", tmpFile, AppName, UpdateDomain, VersionToInstall));

			return 1;
		}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Melz
Только что попробовал на Win10 - работает. Виртуалку с моно я недавно грохнул )

Вы почти угадали :) Есть два (известных мне) способа.

1. Нужно использовать

System.Diagnostics.Process.Start(@"C:\windows\system32\notepad.exe");

Этот способ, тогда дочерний процесс создается с флагом HasExited. Грубо говоря, даете понять что создавший его процесс умер еще до создания и система тогда создаст его самого по себе.

2. Использовать WaitForExit

// Start the child process.
Process p = new Process();
// Redirect the error stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = @"C:\windows\system32\notepad.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected error stream.
// p.WaitForExit();
// Read the error stream first and then wait.
//string error = p.StandardError.ReadToEnd();
p.WaitForExit();

Мы просто говорим чайлду что мол жди закрытия парента бесконечно.

В первом случае консольное приложение закрывается само, оставляя открытым блокнот. Во втором - остается открытым, но при закрытии блокнот все равно остается открытым.

Как оно поведет себя на моно не знаю )) Удачи )
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы