Rumah >pembangunan bahagian belakang >C++ >Bagaimana untuk Memastikan Proses Kanak-kanak Ditamatkan Apabila Aplikasi Induk Ranap dalam C#?

Bagaimana untuk Memastikan Proses Kanak-kanak Ditamatkan Apabila Aplikasi Induk Ranap dalam C#?

Susan Sarandon
Susan Sarandonasal
2025-01-25 04:45:10279semak imbas

How to Ensure Child Processes Terminate When the Parent Application Crashes in C#?

Melaksanakan mekanisme dalam C# untuk proses anak berakhir dengan proses induk

Apabila mencipta proses menggunakan kelas System.Diagnostics.Process, adalah penting untuk memastikan bahawa proses anak juga ditamatkan jika aplikasi induk ranap. Walau bagaimanapun, dalam beberapa kes, seperti apabila menamatkan aplikasi melalui Pengurus Tugas, tingkah laku ini tidak automatik.

Untuk menyelesaikan masalah ini, kami boleh menggunakan "objek pekerjaan" yang disediakan oleh sistem pengendalian Windows. Dengan mencipta objek kerja untuk aplikasi induk dan mendaftarkan proses anak ke dalamnya, kami boleh mewujudkan kebergantungan antara proses. Ini memastikan bahawa sistem pengendalian secara automatik menamatkan proses anak apabila proses induk ditamatkan.

Pelaksanaan objek kerja

Kod berikut menunjukkan cara membuat objek kerja dan mengaitkan proses kanak-kanak dengannya:

<code class="language-csharp">public class Job : IDisposable
{
    private IntPtr m_handle;
    private bool m_disposed = false;

    public Job()
    {
        m_handle = CreateJobObject(IntPtr.Zero, null); // 修正:使用IntPtr.Zero

        JOBOBJECT_BASIC_LIMIT_INFORMATION info = new JOBOBJECT_BASIC_LIMIT_INFORMATION();
        info.LimitFlags = 0x2000; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE

        JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
        extendedInfo.BasicLimitInformation = info;

        int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
        IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
        Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);

        if (!SetInformationJobObject(m_handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
            throw new Exception($"无法设置信息。错误代码:{Marshal.GetLastWin32Error()}"); // 使用插值字符串

        Marshal.FreeHGlobal(extendedInfoPtr); // 释放非托管内存
    }

    public bool AddProcess(IntPtr handle)
    {
        return AssignProcessToJobObject(m_handle, handle);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (m_disposed)
            return;

        if (disposing) { }

        Close();
        m_disposed = true;
    }

    public void Close()
    {
        Win32.CloseHandle(m_handle);
        m_handle = IntPtr.Zero;
    }
}</code>

Barisan utama dalam pembina ialah:

<code class="language-csharp">info.LimitFlags = 0x2000;</code>

Ini menetapkan bendera JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, yang menyatakan bahawa apabila kerja ditutup, semua proses yang dikaitkan dengan tugas itu harus ditamatkan.

Selepas mencipta objek kerja, anda boleh mengaitkan proses anak dengannya menggunakan kaedah AddProcess. Contohnya adalah seperti berikut:

<code class="language-csharp">using Microsoft.Office.Interop.Excel; // 确保引用了Excel互操作库

// ...其他代码...

Excel.Application app = new Excel.ApplicationClass();

uint pid = 0;
Win32.GetWindowThreadProcessId(new IntPtr(app.Hwnd), out pid);
Process process = Process.GetProcessById((int)pid);
job.AddProcess(process.Handle);

// ...其他代码...

// 记得释放COM对象
Marshal.ReleaseComObject(app);
app = null;

// ...其他代码...</code>

Dengan mendaftarkan proses anak dengan objek kerja, anda memastikan proses itu ditamatkan secara automatik walaupun sistem pengendalian ditamatkan secara tiba-tiba. Pengendalian ralat dan keluaran sumber telah ditambahkan pada kod, meningkatkan keteguhan dan kebolehpercayaan kod. Juga, pastikan anda merujuk pustaka interop Excel dengan betul.

Nota: Kaedah ini bergantung pada fungsi objek kerja yang disediakan oleh sistem pengendalian Windows dan hanya terpakai pada platform Windows. Selain itu, anda perlu menambah kernel32.dll pengisytiharan (P/Invoke kelas) untuk Win32 Bahagian ini ditinggalkan dalam kod dan perlu ditambah oleh anda sendiri. Dan perlu mengendalikan kemungkinan pengecualian, seperti proses ketiadaan atau kebenaran tidak mencukupi. Akhir sekali, ingat untuk melepaskan objek COM untuk mengelakkan kebocoran sumber.

Atas ialah kandungan terperinci Bagaimana untuk Memastikan Proses Kanak-kanak Ditamatkan Apabila Aplikasi Induk Ranap dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn