Skip to content

Conversation

Copy link

Copilot AI commented Dec 14, 2025

List of changes

AppiumLocalService now sends CTRL+C to Node.js processes on Windows before forceful termination, allowing cleanup handlers to execute and preventing accumulation of temporary .response files.

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change that adds functionality or value)
  • Breaking change (fix or feature that would cause existing functionality not to work as expected)
  • Test fix (non-breaking change that improves test stability or correctness)

Documentation

  • Have you proposed a file change/ PR with Appium to update documentation?

This can be done by navigating to the documentation section on http://appium.io selecting the appropriate command/endpoint and clicking the 'Edit this doc' link to update documentation

Integration tests

  • Have you provided integration tests for your changes? (required for Bugfix, New feature, or Test fix)

Existing integration tests for service start/stop cover this change. The graceful shutdown path is exercised by all tests that call service.Dispose().

Details

Problem

Process.Kill() on Windows acts as SIGKILL, preventing Node.js exit handlers from running. Result: temporary .response files accumulate indefinitely (300GB+ reported).

Solution

Added TryGracefulShutdownOnWindows() that:

  • Uses P/Invoke to attach to process console
  • Sends CTRL+C event (SIGINT equivalent)
  • Waits 5 seconds for graceful exit
  • Falls back to Kill() on failure or non-Windows platforms

Implementation

private void DestroyProcess()
{
    if (Service == null) return;
    
    try
    {
        // Graceful shutdown on Windows, fallback to Kill() if unsupported/fails
        if (!TryGracefulShutdownOnWindows(Service))
        {
            Service.Kill();
        }
    }
    catch { }
    finally
    {
        Service?.Close();
        SharedHttpClient.Dispose();
    }
}

Platform behavior:

  • Windows: CTRL+C → wait 5s → Kill() if needed
  • Linux/macOS: Existing behavior unchanged (already handles SIGTERM correctly)

P/Invoke APIs used: AttachConsole, GenerateConsoleCtrlEvent, FreeConsole, SetConsoleCtrlHandler

Original prompt

This section details on the original issue you should resolve

<issue_title>[Feat]: Implement graceful shutdown (SIGINT/SIGTERM) for AppiumLocalService on Windows to prevent temp file accumulation</issue_title>
<issue_description>Problem Description
The AppiumLocalService in the .NET client currently uses Process.Kill() (or Dispose()) to stop the local Appium server instance. On Windows, this behaves as a SIGKILL (force termination).

Because the process is force-killed, the Appium Node.js server does not trigger its cleanup logic. As a result, temporary .response files (used for idempotency keys) generated during the session are not deleted. Over time, these files accumulate and can consume significant disk space (reports of >300GB).

Technical Context
Source Issue: appium/dotnet-client#625

Affected Platform: Windows (macOS/Linux handle SIGTERM correctly via Dispose).

Root Cause: The Kill() method does not allow the Node.js process to run its exit or SIGINT handlers.

Failed Attempts:

Process.CloseMainWindow(): Does not work if the server is started without a visible window (background process).

GenerateConsoleCtrlEvent: Unreliable for background processes started via AppiumLocalService.

Requirements
We need to implement a mechanism in AppiumLocalService that sends a graceful termination signal (equivalent to SIGINT or SIGTERM) to the Node.js process on Windows.

Potential Solutions to Explore
Window Management: Start the process with a visible window but immediately hide it via P/Invoke, allowing CloseMainWindow to function correctly later.

IPC/Signal: Use a dedicated mechanism or P/Invoke to send CTRL_C_EVENT specifically to the child Node process group.

Process Management: Review how other .NET wrappers for Node.js services handle graceful shutdowns on Windows.

Reproduction
Start an AppiumLocalService instance on Windows.

Run a test that generates session requests (creating .response temp files).

Call service.Dispose().

Observe that the Appium process dies immediately and .response files remain in the temp folder.</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits December 14, 2025 22:11
Co-authored-by: Dor-bl <59066376+Dor-bl@users.noreply.github.com>
Co-authored-by: Dor-bl <59066376+Dor-bl@users.noreply.github.com>
Co-authored-by: Dor-bl <59066376+Dor-bl@users.noreply.github.com>
Copilot AI changed the title [WIP] Add graceful shutdown for AppiumLocalService on Windows Implement graceful shutdown for AppiumLocalService on Windows to prevent temp file accumulation Dec 14, 2025
Copilot AI requested a review from Dor-bl December 14, 2025 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat]: Implement graceful shutdown (SIGINT/SIGTERM) for AppiumLocalService on Windows to prevent temp file accumulation

2 participants