Repository: terminal
Issue: User32.dll Import Cause Windows Terminal Crash
Labels: Issue-Bug,Needs-Triage

### Windows Terminal version

1.21.3231.0

### Windows build number

10.0.26100.0 

### Other Software

_No response_

### Steps to reproduce

## Problem Statement

It seems like the use of user32.dll could cause stability issue on Windows terminal. Eventually, it will cause the crash. 

This issue only happens with a small possibility when the command is executed (<0.1% chance/cycle). But when we put this in a while loop a run the same script across 200+ machines, it will happen everyday. 

In this case, I isolated the code to reproduce this problem. 
* run following code as administrator. 
* start another 15 terminals to run that in parallel. 


## Code to reproduce
```powershell
function Out-ProcessEx {
    param
    (
        [Parameter(Mandatory, ValueFromPipeline)]
        $process
    )
  
    
    process {
        #Get Window Title, We use this function because default PowerShell function cannot get 
        #title for hidden window
        $wTitle = Get-WindowTitleFromProcessId -processId $process.Id

        # update MainWindowTitle
        $field = $process.GetType().GetField("mainWindowTitle", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Public)
        $field.SetValue($process, $wTitle)

    
        $process 
    }  
}


function Get-WindowHandleFromProcessId {
    param (
        [Parameter(Mandatory = $true)]
        [int]$ProcessId
    )
 
    # Define the necessary functions from user32.dll
    Add-Type @"
using System;
using System.Runtime.InteropServices;
 
public class User32 {
    public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
 
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
 
    [DllImport("user32.dll", SetLastError = true)]
    public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);
}
"@ -ErrorAction SilentlyContinue
 
    $Script:windowHandle = 0
 
    $callback = [User32+EnumWindowsProc] {
        param ($hWnd, $lParam)
        $processId = 0
        [User32]::GetWindowThreadProcessId($hWnd, [ref]$processId) | Out-Null
        if ([int]($processId) -eq [int]($lParam)) {
            $Script:windowHandle = $hWnd
            return $false  # Stop enumeration
        }
 
        return $true  # Continue enumeration
    }
 
    [User32]::EnumWindows($callback, [IntPtr]$ProcessId) | Out-Null
 
    return $Script:windowHandle
}

 
function Get-WindowTitleFromProcessId {
    param (
        [Parameter(Mandatory = $true)]
        [Int]$processId
    )
    # Define the necessary functions from user32.dll
    Add-Type @"
using System;
using System.Text;
using System.Runtime.InteropServices;
 
public class WindowTitleFromHandle {
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
 
    [DllImport("user32.dll", SetLastError = true)]
    public static extern int GetWindowTextLength(IntPtr hWnd);
}
"@ -ErrorAction SilentlyContinue
    $WindowHandle = Get-WindowHandleFromProcessId -ProcessId $processId
    $length = [WindowTitleFromHandle]::GetWindowTextLength($WindowHandle)
    if ($length -gt 0) {
        $builder = New-Object System.Text.StringBuilder -ArgumentList ($length + 1)
        [WindowTitleFromHandle]::GetWindowText($WindowHandle, $builder, $builder.Capacity) | Out-Null
        return $builder.ToString()
    }
    else {
        return "No title found"
    }
}
while($true)
{
$s1 = Get-Process|Out-ProcessEx
#start 16 process and see......
}
```

## Error Log

![Image](https://github.com/user-attachments/assets/e98509ef-bf6a-44c6-acc3-54ea18276cb7)

![Image](https://github.com/user-attachments/assets/7ed03a72-3995-4db8-b1d1-5a824d4ef95b)

 

### Expected Behavior

16 instances of windows terminal should persist after 20 minutes

### Actual Behavior

* The crash issue typically occur after ~ 15-20mins.