fix: dispatch controlled AutoCAD exit from idle
This commit is contained in:
@@ -128,6 +128,7 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
private int? before, after1, after2, afterUndo;
|
private int? before, after1, after2, afterUndo;
|
||||||
private AutomationEntityCounts? baseline, counts1, counts2, countsUndo;
|
private AutomationEntityCounts? baseline, counts1, counts2, countsUndo;
|
||||||
private readonly List<string> transitions = ["Created"];
|
private readonly List<string> transitions = ["Created"];
|
||||||
|
private bool exitQueued;
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
@@ -164,8 +165,7 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
{
|
{
|
||||||
transitions.Add("LifecycleProbeCompleted");
|
transitions.Add("LifecycleProbeCompleted");
|
||||||
WriteEvidence(true, null);
|
WriteEvidence(true, null);
|
||||||
transitions.Add("ExitRequested");
|
RequestControlledExit();
|
||||||
AcadApplication.Quit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnIdle(object? sender, EventArgs e)
|
private void OnIdle(object? sender, EventArgs e)
|
||||||
@@ -256,12 +256,40 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
AcadApplication.DocumentManager.DocumentActivated -= OnDocumentActivated;
|
AcadApplication.DocumentManager.DocumentActivated -= OnDocumentActivated;
|
||||||
WriteEvidence(success, error);
|
WriteEvidence(success, error);
|
||||||
if (document is not null) document.CloseAndDiscard();
|
if (document is not null) document.CloseAndDiscard();
|
||||||
AcadApplication.Quit();
|
RequestControlledExit();
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
finally { selectedTargetSnapshotId = null; pxpResults.Clear(); }
|
finally { selectedTargetSnapshotId = null; pxpResults.Clear(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AutoCAD's direct Application.Quit can leave a startup-script host alive.
|
||||||
|
// Dispatching the native QUIT command from the next quiescent Idle cycle
|
||||||
|
// preserves normal command shutdown semantics.
|
||||||
|
private void RequestControlledExit()
|
||||||
|
{
|
||||||
|
if (exitQueued) return;
|
||||||
|
exitQueued = true;
|
||||||
|
transitions.Add("ExitQueued");
|
||||||
|
AcadApplication.Idle += OnExitIdle;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnExitIdle(object? sender, EventArgs args)
|
||||||
|
{
|
||||||
|
AcadApplication.Idle -= OnExitIdle;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var active = AcadApplication.DocumentManager.MdiActiveDocument;
|
||||||
|
if (active is null) { AcadApplication.Quit(); return; }
|
||||||
|
transitions.Add("NativeQuitDispatched");
|
||||||
|
active.SendStringToExecute("_.QUIT _N ", true, false, false);
|
||||||
|
}
|
||||||
|
catch (System.Exception exception)
|
||||||
|
{
|
||||||
|
RuntimeDiagnostics.Write("AutomationControlledExitFailed", "ERROR", resultStatus: "AUTOMATION_CONTROLLED_EXIT_FAILED", exception: exception);
|
||||||
|
AcadApplication.Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void WriteEvidence(bool success, string? error)
|
private void WriteEvidence(bool success, string? error)
|
||||||
{
|
{
|
||||||
if (config is null) return;
|
if (config is null) return;
|
||||||
|
|||||||
@@ -82,6 +82,14 @@ public sealed class FoundationTests
|
|||||||
Assert.Contains("PostStartupReady", source);
|
Assert.Contains("PostStartupReady", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact] public void AutomationControlledExit_UsesNativeQuitFromIdle()
|
||||||
|
{
|
||||||
|
var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs"));
|
||||||
|
Assert.Contains("RequestControlledExit", source);
|
||||||
|
Assert.Contains("AcadApplication.Idle += OnExitIdle", source);
|
||||||
|
Assert.Contains("active.SendStringToExecute(\"_.QUIT _N \", true, false, false)", source);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact] public void PrimaryCommand_IsRegistered() => Assert.Contains("[CommandMethod(\"PHP_REC_ANNOT\")]", File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")));
|
[Fact] public void PrimaryCommand_IsRegistered() => Assert.Contains("[CommandMethod(\"PHP_REC_ANNOT\")]", File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")));
|
||||||
[Fact] public void LegacyAliases_AreRegistered() => Assert.True(File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")).Contains("PXP-AAV") && File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")).Contains("PXP-OA"));
|
[Fact] public void LegacyAliases_AreRegistered() => Assert.True(File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")).Contains("PXP-AAV") && File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")).Contains("PXP-OA"));
|
||||||
[Fact] public void RibbonCommand_ReferencesRegisteredCommand() => Assert.Contains("PHP_REC_ANNOT ", File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")));
|
[Fact] public void RibbonCommand_ReferencesRegisteredCommand() => Assert.Contains("PHP_REC_ANNOT ", File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "EntryPoint.cs")));
|
||||||
|
|||||||
Reference in New Issue
Block a user