Skip to content

Memory Mapped File

Published: 2025-02-16

Main Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
try {
    # Generate unique GUIDs for MMF and EventWaitHandle
    $mmfID = [System.Guid]::NewGuid().ToString()
    $evntID = [System.Guid]::NewGuid().ToString()

    Write-Host "Generated MMF ID: $mmfID"
    Write-Host "Generated EventWaitHandle ID: $evntID"

    # Create an EventWaitHandle for synchronization BEFORE starting the second script
    $evnt = [System.Threading.EventWaitHandle]::new($false, `
        [System.Threading.EventResetMode]::AutoReset, "Global\$evntID")

    # Create the Memory-Mapped File (MMF) before calling the second script
    $mmf = [System.IO.MemoryMappedFiles.MemoryMappedFile]::CreateOrOpen("Global\$mmfID", 1024)

    # Start the second script and pass both IDs as arguments
    $secondScriptPath = ".\second.ps1"  # Adjust path if necessary
    Start-Process -FilePath "powershell.exe" -ArgumentList `
                "-File `"$secondScriptPath`" `"$mmfID`" `"$evntID`"" -NoNewWindow

    Write-Host "Waiting for data from second script... (Timeout: 60s)"

    # Wait for event signal (timeout after 60 seconds)
    if (-not $evnt.WaitOne(60000)) {
        throw "Timeout: No data received within 60 seconds."
    }

    Write-Host "Data received. Reading from Memory-Mapped File..."

    # Create a view stream for reading data
    $stream = $mmf.CreateViewStream()
    $reader = [System.IO.StreamReader]::new($stream)

    # Read the JSON data from the MMF
    $jsonRead = $reader.ReadLine()

    if (-not $jsonRead) {
        throw "Error: No data found in memory-mapped file."
    }

    # Try to parse the JSON data
    try {
        $pgpDeTaskInfo = $jsonRead | ConvertFrom-Json
    } catch {
        throw "Error parsing JSON data: $_"
    }

    Write-Host "Successfully received and parsed JSON data:"
    Write-Host $pgpDeTaskInfo

} catch {
    Write-Host "An error occurred: $_" -ForegroundColor Red
} finally {
    # Ensure cleanup of resources
    if ($reader) { $reader.Close() }
    if ($stream) { $stream.Close() }
    if ($mmf) { $mmf.Dispose() }
    Write-Host "Resources cleaned up."
}

Second Script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
param (
    [string]$passedMmfID,   # Receive the MMF ID from the main script
    [string]$passedEventID  # Receive the EventWaitHandle ID from the main script
)

try {
    Write-Host "Second script started. Using MMF ID: $passedMmfID"
    Write-Host "Using EventWaitHandle ID: $passedEventID"

    # Simulating processing time
    Start-Sleep -Seconds 2

    # Define some example data
    $errorCode = 0
    $errorDescription = "Error description."

    # Define a custom object for the data we want to send back
    $taskInfo = [PSCustomObject]@{
        ErrorCode        = $errorCode
        ErrorDescription = "${errorDescription}"
    }

    $jsonData = $taskInfo | ConvertTo-Json -Compress

    # Open the memory-mapped file using the passed MMF ID
    $mmf = [System.IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting("Global\$passedMmfID")
    $stream = $mmf.CreateViewStream()
    $writer = New-Object System.IO.StreamWriter($stream)
    $writer.AutoFlush = $true  # Ensures data is written immediately

    Write-Host "Writing JSON data to MMF..."
    # Write the JSON string to the memory-mapped file
    $writer.WriteLine($jsonData)

    # Open the named EventWaitHandle to signal completion
    $evnt = [System.Threading.EventWaitHandle]::new($false, `
        [System.Threading.EventResetMode]::AutoReset, "Global\$passedEventID")

    # Signal the event to notify the main script that data is available
    $evnt.Set() | Out-Null

    Write-Host "Data sent successfully."

} catch {
    Write-Host "An error occurred in the second script: $_" -ForegroundColor Red
} finally {
    # Ensure cleanup of resources
    if ($writer) { $writer.Close() }
    if ($stream) { $stream.Close() }
    if ($mmf) { $mmf.Dispose() }
    Write-Host "Second script resources cleaned up."
}