我有一个 WPF 应用程序,在处理文件时需要使用 docker 进程。 docker 容器构建在盒子上,当前使用 WPF 应用程序处理文件后,用户必须启动命令提示符并输入
docker run --it --rm -v folderdedirect process parameters_including_filePath
进行进一步加工。
我想将其包含在 WPF 应用程序中。我大概可以将
system.diagnostics.process
与 cmd.exe
一起使用吗?我查看了 Docker.dotnet
,但我一生都无法弄清楚它应该如何运行本地容器。
这就是我最终的做法,但可能还有更好的方法。
var processInfo = new ProcessStartInfo("docker", $"run -it --rm blahblahblah");
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
int exitCode;
using (var process = new Process())
{
process.StartInfo = processInfo;
process.OutputDataReceived += new DataReceivedEventHandler(logOrWhatever());
process.ErrorDataReceived += new DataReceivedEventHandler(logOrWhatever());
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit(1200000);
if (!process.HasExited)
{
process.Kill();
}
exitCode = process.ExitCode;
process.Close();
}
更现代的解决方案将与包一起使用
DotNet.Testcontainers.Builders
这里是代码示例及其用法:
ContainerBuilder builder = new ContainerBuilder()
// use particular version always
.WithImage("postgres")
// name it nicely
.WithName("PSQL")
.WithBindMount("/var/run/docker.sock", "/var/run/docker.sock")
// with some configuration
.WithEnvironment(new Dictionary<string, string>())
.WithEnvironment("DOCKER_HOST", "unix:///var/run/docker.sock")
.WithWaitStrategy(Wait.ForUnixContainer())
.WithOutputConsumer(Consume.RedirectStdoutAndStderrToConsole());
builder = builder.WithPortBinding(5432, 5432);
PsqlStack = builder.Build();
await PsqlStack.StartAsync();
根据我的上下文修改了上面的代码。最困难的部分是确定如何监控流程是否完成。您可以尝试设置事件侦听器,如此处所示。有其他条件需要验证(如果客户端发送终止信号),我决定继续监视 process.HasExited 值。
private static void RunDockerImage(ContainerData containerData)
{
var processInfo = new ProcessStartInfo("docker", $"run "+containerData.ImageName);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.RedirectStandardError = true;
int exitCode;
using (var process = new Process())
{
process.StartInfo = processInfo;
// indicate process is started
StartUpdateOrch(containerData);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
while(!process.HasExited)
{
// continually check if kill signal is set
if (getKillSignal())
{
process.Kill();
}
Thread.Sleep(2000);
}
exitCode = process.ExitCode;
containerData.exitCode = exitCode;
// indicate process is done
FinishUpdateOrch(containerData);
process.Close();
}
}