Implémentation du mécanisme en C# pour que le processus enfant se termine avec le processus parent
Lors de la création d'un processus à l'aide de la classe System.Diagnostics.Process
, il est crucial de s'assurer que le processus enfant se termine également si l'application parent plante. Cependant, dans certains cas, comme lors de la fermeture d'une application via le Gestionnaire des tâches, ce comportement n'est pas automatique.
Afin de résoudre ce problème, nous pouvons utiliser le "job object" fourni par le système d'exploitation Windows. En créant un objet de travail pour l'application parent et en y enregistrant le processus enfant, nous pouvons établir des dépendances entre les processus. Cela garantit que le système d'exploitation met automatiquement fin au processus enfant lorsque le processus parent se termine.
Mise en œuvre de l'objet de travail
Le code suivant montre comment créer un objet de travail et lui associer un processus enfant :
<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>
La ligne clé du constructeur est :
<code class="language-csharp">info.LimitFlags = 0x2000;</code>
Ceci définit l'indicateur JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
, qui spécifie que lorsqu'un travail est fermé, tous les processus associés au travail doivent se terminer.
Après avoir créé un objet job, vous pouvez lui associer un processus enfant à l'aide de la méthode AddProcess
. Un exemple est le suivant :
<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>
En enregistrant les processus enfants avec un objet de travail, vous vous assurez qu'ils sont automatiquement terminés même si le système d'exploitation s'arrête soudainement. La gestion des erreurs et la libération des ressources ont été ajoutées au code, améliorant ainsi la robustesse et la fiabilité du code. Assurez-vous également de référencer correctement la bibliothèque interop Excel.
Remarque : Cette méthode s'appuie sur la fonction d'objet de travail fournie par le système d'exploitation Windows et n'est applicable qu'à la plate-forme Windows. De plus, vous devez ajouter la déclaration kernel32.dll
(classe P/Invoke
) pour Win32
. Cette partie est omise dans le code et doit être complétée par vous-même. Et vous devez gérer des exceptions potentielles, telles que l'inexistence de processus ou des autorisations insuffisantes. Enfin, pensez à libérer l'objet COM pour éviter les fuites de ressources.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!