Sep 03 2023 10:38 AM - edited Sep 03 2023 10:40 AM
I’m writing a PowerShell script to start a container and stop WSL safely when the container stops. Here is my attempt:
$ContainerName = 'tranky' $DockerDesktopPath = "C:\Program Files\Docker\Docker\Docker Desktop.exe" Start-Process $DockerDesktopPath $id = (Get-Process 'Docker Desktop').id Wait-Process -id $id docker start $ContainerName docker wait $ContainerName $IsContainerRunning = docker container inspect -f '{{.State.Running}}' $ContainerName $IsDockerDesktopRunning = Get-Process "Docker Desktop" -ErrorAction SilentlyContinue while ($IsContainerRunning -eq $true) { Start-Sleep -Seconds 5 $IsContainerRunning = docker container inspect -f '{{.State.Running}}' $ContainerName } if ($IsDockerDesktopRunning && $IsContainerRunning) { $IsDockerDesktopRunning.CloseMainWindow() $IsDockerDesktopRunning | Stop-Process -Force } wsl --shutdown
Currently, I’m stuck at this part:
Start-Process $DockerDesktopPath $id = (Get-Process 'Docker Desktop').id Wait-Process -id $id
If I don’t wait for the process to finish, then I can’t call docker start. However, if I do that, then it won’t finish even though Docker Desktop has already popped up and is doing nothing. I also want to have the log of the container to be displayed in the host’s terminal. Any suggestion?
Sep 04 2023 04:34 AM
I don't know anything about Docker, but I can try and help with your first question (though not the second question about logging).
When you say that docker start fails, what does that look like? Is it just that nothing happens, or do you get a detailed error message?
If you put a large delay after the Start-Process (i.e. Start-Sleep -Seconds 20) and before the docker start, does the the docker start work then?
Do you know if the Docker desktop process spawns any child processes you can monitor for?
Knowing some of this may help us help you with the first question.
Cheers,
Lain
Sep 05 2023 08:50 AM
Sep 05 2023 09:11 AM
There's no single, generic way to know that.
At best, there might be a way that's specific to the exact application/service you're working with, but for another application/service, it might require a completely different approach - or there may be no way at all. It's not like Windows prescribes a standard that client processes have to confirm to/integrate with.
Take Docker, for example. If the "Docker Desktop" you're launching were to in turn launch (or stop) child processes of its own, then you could leverage that behaviour. But let's say it doesn't, then you may have no visibility into how it's going with its start-up routine at which point all you can do is wait an arbitrary interval (or variations of that such as polling, but this isn't always materially any better).
Cheers,
Lain
Sep 06 2023 08:34 AM
I see. So if an app wants to implement this, what would be the way for it to do so? What teens should I look for?
Sep 06 2023 07:17 PM
I don't quite understand the question. What are teens? (Excluding rambunctious kids.)
Cheers,
Lain
Sep 07 2023 01:33 AM - edited Sep 08 2023 12:51 AM
oh it's autocorrect . I was asking "what terms should I look for?"
Sep 07 2023 02:18 AM
I can't tell you what to look for with Docker, as I don't use it.
The best I can do is provide you with a hypothetical example for a scenario where the first program you start with Start-Process (in your case, this is Docker Desktop) then starts another child process of its own, indicating it's operational.
Because I don't use Docker, I have to use other programs in the example. Here's a table that translates what I'm using for illustrative purposes to what you would use.
Stage | My example | Your scenario |
Start-Process | cmd.exe | Docker Desktop |
Child process | notepad.exe | <something Docker launches> |
# Launch the "main" process.
$Process = Start-Process -FilePath "cmd.exe" -PassThru -ErrorAction:Stop;
# Monitor for a specific child process being launched by the main process.
$CheckAgain = $true;
$Retries = 10;
while ($CheckAgain -and ($Retries -gt 0))
{
if (Get-CimInstance -ClassName "Win32_Process" -Filter "ParentProcessID=$($Process.Id) AND Name='notepad.exe'")
{
$CheckAgain = $false;
}
else
{
$Retries--;
Start-Sleep -Seconds 2;
}
}
Here, we're checking for a maximum of 20 seconds ([10 retries] x [two second sleep] to see if the child process has started. If it starts earlier, then the loop will exit earlier.
But again, this is hypothetical and may not be useful for your Docker scenario at all. You'd have to do some investigating to see how Docker behaves before you can solve your challenge.
Cheers,
Lain
Sep 08 2023 12:50 AM
Actually I was broadening my topic and not talking about Docker specifically. Like, if I'm writing a program and want to register my program's events to the OS so that users can take it from there, what should I do? Only signalling via child process seems limited to me. I guess the only way to communicate with the OS is to pack all the information in the process title. I see that the Task Scheduler is something in the right way.
Sep 08 2023 03:57 AM
Okay, so setting Docker aside, there's no mandated standard.
The closest thing to a standard would be making use of the Windows event logs, where your application would write key events to either the Application log (most common as it's the oldest and therefore the most well-known log) or the Application and Services Logs node (newer, uses and different implementation and isn't widely used by vendors outside of Microsoft - though it is growing.)
Ultimately it's entirely up to the developer how they wish to inform of key events - or even to not inform at all. Again, there is no mandated standard for this.
But this is a discussion for another forum as it is entirely unrelated to PowerShell.
Cheers,
Lain