Stardust/Doc/ProcessStart.md

10 KiB
Raw Permalink Blame History

Process启动进程研究

研究目标

A应用通过Process类启动B应用研究不同参数设置下的测试结果。

测试准备

.Net版本net8.0

星尘代理:/root/agent

A目录/root/TestA 主程序

B目录/root/TestB 目标NewLife应用

C目录/root/TestC 目标net8应用

D目录/root/TestD 目标非托管应用

跟随退出随着A应用退出B应用跟随退出

测试逻辑A应用设置不同参数启动B应用然后A先退出观察B是否跟随退出。

测试程序:

using System.Diagnostics;
using NewLife;
using NewLife.Log;

XTrace.UseConsole();

XTrace.WriteLine("TestA启动PID={0}", Process.GetCurrentProcess().Id);
XTrace.WriteLine("测试参数:{0}", args.Join(" "));

var target = "TestB";
if (args.Contains("-c"))
    target = "TestC";

var old = Process.GetProcesses().FirstOrDefault(e => e.ProcessName == target);
if (old != null)
{
    XTrace.WriteLine("关闭进程 {0} {1}", old.Id, old.ProcessName);
    old.Kill();
}

var si = new ProcessStartInfo
{
    FileName = (Runtime.Windows ? $"../{target}/{target}.exe" : $"../{target}/{target}").GetFullPath(),
    Arguments = "-name NewLife",
    //WorkingDirectory = "",
    //UseShellExecute = false,
};

// 必须在si.Environment之前设置否则丢失。可能si.Environment复制了一份
if (args.Contains("-b")) Environment.SetEnvironmentVariable("BasePath", $"../{target}".GetFullPath());
if (args.Contains("-s")) si.UseShellExecute = true;
if (args.Contains("-w")) si.WorkingDirectory = Path.GetDirectoryName(si.FileName)?.GetFullPath();
if (args.Contains("-e")) si.Environment["star"] = "dust";

XTrace.WriteLine("UseShellExecute:\t{0}", si.UseShellExecute);
XTrace.WriteLine("WorkingDirectory:\t{0}", si.WorkingDirectory);

var p = Process.Start(si);
if (p == null || p.WaitForExit(3_000) && p.ExitCode != 0)
{
    XTrace.WriteLine("启动失败ExitCode={0}", p?.ExitCode);
}
else
{
    XTrace.WriteLine("启动成功PID={0}", p.Id);
}

Console.WriteLine("TestA OK!");
//Console.ReadKey();
Thread.Sleep(5_000);

分类测试

根据不同类型的B应用分类测试。

NewLife应用测试

要求B应用必须引入NewLife.Core它能收到环境变量BasePath并自动调整当前目录。

win10执行命令的目录D:\X\Stardust\Bin\Samples

centos执行命令的目录/root

系统/参数 Shell WorkingDirectory Environment 合并输出 跟随退出 结果CurrentDirectory
win10 false Y N \Samples
TestA.exe -b -e false star=dust Y N \Samples
TestA.exe -w false \Samples\TestB Y N \Samples\TestB
TestA.exe -w -b -e false \Samples\TestB BasePath=xxx Y N \Samples\TestB
TestA.exe -s true N N \Samples
TestA.exe -s -b -e true 要求shell=false ==报错==
TestA.exe -s -w true \Samples\TestB N N \Samples\TestB
TestA.exe -s -w -b true \Samples\TestB BasePath=xxx N N \Samples\TestB
CentOS7.9 false Y N /root
TestA -b -e false star=dust Y N /root
TestA -w false /root/TestB Y N /root/TestB
TestA -w -b -e false /root/TestB BasePath=xxx Y N /root/TestB
TestA -s true Y N /root
TestA -s -b -e true BasePath=xxx Y N /root
TestA -s -w true /root/TestB Y N /root/TestB
TestA -s -w -b -e true /root/TestB BasePath=xxx Y N /root/TestB

测试结论:

  1. 目标B应用的当前目录取决于WorkingDirectory如果未设置则取A应用的当前目录非A工作目录

  2. windows上UseShellExecute=true时目标B应用输出不会合并到A窗口而是独立窗口

  3. 所有测试用例B都不会跟随A退出。该结论跟星尘代理现状不一致后者会跟随退出

  4. 进程的Environment环境变量在windows下要求UseShellExecute=falseLinux下则无此要求

Net8应用测试

要求C应用是普通net8应用禁止引入NewLife.Core。

win10执行命令的目录D:\X\Stardust\Bin\Samples

centos执行命令的目录/root

系统/参数 Shell WorkingDirectory Environment 合并输出 跟随退出 结果CurrentDirectory
win10 false Y N \Samples
TestA.exe -c -b -e false star=dust Y N \Samples
TestA.exe -c -w false \Samples\TestC Y N \Samples\TestC
TestA.exe -c -w -b -e false \Samples\TestC BasePath=xxx Y N \Samples\TestC
TestA.exe -c -s true N N \Samples
TestA.exe -c -s -b -e true 要求shell=false ==报错==
TestA.exe -c -s -w true \Samples\TestC N N \Samples\TestC
TestA.exe -c -s -w -b true \Samples\TestC BasePath=xxx N N \Samples\TestC
CentOS7.9 false Y N /root
TestA -c -b -e false star=dust Y N /root
TestA -c -w false /root/TestC Y N /root/TestC
TestA -c -w -b -e false /root/TestC BasePath=xxx Y N /root/TestC
TestA -c -s true Y N /root
TestA -c -s -b -e true BasePath=xxx Y N /root
TestA -c -s -w true /root/TestC Y N /root/TestC
TestA -c -s -w -b -e true /root/TestC BasePath=xxx Y N /root/TestC

测试结论:

  1. net8应用测试表现跟NewLife应用一致

  2. 目标C应用的当前目录取决于WorkingDirectory如果未设置则取A应用的当前目录非A工作目录

  3. windows上UseShellExecute=true时目标C应用输出不会合并到A窗口而是独立窗口

  4. 所有测试用例C都不会跟随A退出。该结论跟星尘代理现状不一致后者会跟随退出

  5. 进程的Environment环境变量在windows下要求UseShellExecute=falseLinux下则无此要求

非托管应用测试

要求B应用必须是非托管应用。

win10执行命令的目录D:\X\Stardust\Bin\Samples

centos执行命令的目录/root

系统/参数 Shell WorkingDirectory Environment 合并输出 跟随退出 结果CurrentDirectory
win10 false Y N \Samples
TestA.exe -d -b -e false star=dust Y N \Samples
TestA.exe -d -w false \Samples\TestD Y N \Samples\TestD
TestA.exe -d -w -b -e false \Samples\TestD BasePath=xxx Y N \Samples\TestD
TestA.exe -d -s true N N \Samples
TestA.exe -d -s -b -e true 要求shell=false ==报错==
TestA.exe -d -s -w true \Samples\TestD N N \Samples\TestD
TestA.exe -d -s -w -b true \Samples\TestD BasePath=xxx N N \Samples\TestD
CentOS7.9 false Y N /root
TestA -d -b -e false star=dust Y N /root
TestA -d -w false /root/TestD Y N /root/TestD
TestA -d -w -b -e false /root/TestD BasePath=xxx Y N /root/TestD
TestA -d -s true Y N /root
TestA -d -s -b -e true BasePath=xxx Y N /root
TestA -d -s -w true /root/TestD Y N /root/TestD
TestA -d -s -w -b -e true /root/TestD BasePath=xxx Y N /root/TestD

测试结论:

  1. 目标B应用的当前目录取决于WorkingDirectory如果未设置则取A应用的当前目录非A工作目录

  2. windows上UseShellExecute=true时目标B应用输出不会合并到A窗口而是独立窗口

  3. 所有测试用例B都不会跟随A退出。该结论跟星尘代理现状不一致后者会跟随退出

  4. 进程的Environment环境变量在windows下要求UseShellExecute=falseLinux下则无此要求