Przekazanie obiektu uruchomionego procesu do metody zawartej w innej klasie nie wskazuje na uruchomiony proces

0

Witam,

  • Prosta aplikacja w Windows Forms
  • Na drugiej formie odpalany jest proces i jest oczekiwanie na wyjsćie
  • w zależności od ExitCode ustalany jest kolor

Kod Form1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PassingToForm {
    public partial class EETLauncherMain : Form {
        public EETLauncherMain() {
            InitializeComponent();
        }

        private void button1_Click( object sender, EventArgs e ) {
            EETLauncherSettings frm = new EETLauncherSettings( this );
            frm.Show();
        }
    }

    public class Ex
    {
        public static Process StartP( ProcessStartInfo StartInfo )
        {
            using ( var process = new Process { StartInfo = StartInfo } ) {
                try {
                    process.Start();
                    process.WaitForExit();
                } catch ( Exception ex ) {
                    File.AppendAllText( @"C:\Users\ALIEN\EETLauncher.log", Convert.ToString( ex.Message ) + "\r\n" );
                }
                try {
                    process.GetType();
                } catch ( InvalidOperationException ex ) {
                    File.AppendAllText( @"C:\Users\ALIEN\EETLauncher.log", Convert.ToString( ex.Message ) + "\r\n" );
                } catch ( Exception ex ) {
                    File.AppendAllText( @"C:\Users\ALIEN\EETLauncher.log", Convert.ToString( ex.Message ) + "\r\n" );
                }
                return process;
            }
        }
        public static bool GetProcesExitState( Process Process ) {
            try {
                var ps = Process.GetProcesses().Single(
                    p => p.Id != 0 && p.Handle == Process.Handle );
                return ps.ExitCode == 0;
            } catch ( Exception ex ) {
                File.AppendAllText( @"C:\Users\ALIEN\EETLauncher.log", Convert.ToString( ex.Message ) + "\r\n" );
                return false;
            }
        }
    }
}

Kod Form2

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;

namespace PassingToForm {
    public partial class EETLauncherSettings : Form {
        public EETLauncherSettings() {
            InitializeComponent();
        }

        private EETLauncherMain mainForm;
        public EETLauncherSettings( Form callingForm ) {
            mainForm = callingForm as EETLauncherMain;
            InitializeComponent();
        }

        private void EETLauncherSettings_Load( object sender, EventArgs e ) {

        }
        private void button2_Click( object sender, EventArgs e )
        {
            var ps = Ex.StartP( SetProcessStartInfo() );
            var state = Ex.GetProcesExitState( ps );
            if ( state ) {
                ForeColor = Color.Green;
            }
            if ( state == false ) {
                ForeColor = Color.Red;
            }
        }

        public static ProcessStartInfo SetProcessStartInfo() {
            return new ProcessStartInfo {
                WorkingDirectory = Path.GetDirectoryName( Application.ExecutablePath ) ?? throw new InvalidOperationException(),
                FileName = @"Notepad.exe",
                CreateNoWindow = true,
                UseShellExecute = false
            };
        }


    }
}

Jak tylko przeniosę metodę SetProcessStartInfo do Form2 kod działa i obiekt przekazywany jest poprawnie do sprawdzania ExitCode. Dlaczego? Przecież przekazuję przypisany obiekt procesu?

0

Być może jest to pytanie na kategorię typu "Newbie" ale naprawdę chciałbym wiedzieć. Czy winą może być użycie "using" ? Korzystam z tego aby automatycznie zwolnić zasoby po tym jak proces się zakończy.

1

Problemem jest to że próbujesz operować na obiekcie Process poza blokiem using który jak wiesz zwalnia zasoby, skoro zasoby zostały zwolnione no to późniejsze odwołanie do tego obiektu w metodzie GetProcesExitState rzuca wyjątkiem.

0

Wobec powyższego, poprawnie myślę, że:

return process;

nigdy nie zwróci obiektu procesu bo on jest niszczony poprzez zastosowanie "using" ?

1

No powiedzmy, kierunek dobry, ale słownictwo nieprecyzyjne, obiekt będzie zwrócony ale prawdopodobnie już nic pożytecznego z nim się nie zrobi bo zasoby niezarządzane (uchwyt do procesu systemwoego) na których operował zostały zwolnione.

1 użytkowników online, w tym zalogowanych: 0, gości: 1