Methods to start process in C# and powershell

private int StartProcess(SoftwareSvr swSvr, string workingDir)
{
    Process proc = new Process();
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.WorkingDirectory = workingDir;
    proc.StartInfo.FileName = swSvr.Command;

    if (swSvr.Args != null && swSvr.Args.Any())
    {
        proc.StartInfo.Arguments = string.Join(' ', swSvr.Args);
    }

    bool started = proc.Start();

    if (started)
    {
        return proc.Id;
    }
    else
    {
        return -1;
    }
}
private int StartProcessByPs(SoftwareSvr swSvr, string workingDir)
{
    /*
     * 1. wmic process call create "cluster\GatewayServer.exe start -id 1", "c:\app\", 但wmic启动的进程中不使用系统的环境变量
     * 2. powershell -Command "try{$app = Start-Process -PassThru -FilePath \"cluster\GatewayServer.exe\" -WorkingDirectory \"C:\app\" -ArgumentList \"start -id 5\";echo $app.Id} catch {throw}"
     */
    Process proc = new Process();
    proc.StartInfo.WorkingDirectory = workingDir;
    proc.StartInfo.FileName = @"C:\windows\system32\cmd.exe";
    proc.StartInfo.RedirectStandardOutput = true;
    var psArgs = string.Empty;

    if (swSvr.Args != null && swSvr.Args.Any())
    {
        psArgs = " -ArgumentList \\\"{string.Join(' ', swSvr.Args)}\\\"";
    }

    var psCmd = $"/C powershell -Command \"try{{$app = Start-Process -PassThru -FilePath \\\"{swSvr.Command}\\\" -WorkingDirectory \\\"{workingDir}\\\"{psArgs};echo $app.Id}} catch {{throw}}\"";
    proc.StartInfo.Arguments = psCmd;
    proc.Start();
    proc.WaitForExit();
    var output = proc.StandardOutput.ReadToEnd();

    if (proc.ExitCode != 0)
    {
        _logger.LogWarning($"Failed to start process: {proc.StartInfo.Arguments}, output: {output}");
        return -1;
    }
    else
    {
        return int.Parse(output);
    }
}

In Powershell

$taskName = "DelayStartup";


$t = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(2);
$t.EndBoundary = (Get-Date).AddSeconds(60).ToString('s');
Register-ScheduledTask -Force -TaskName $taskName -Action (New-ScheduledTaskAction -Execute C:\test.bat) -Trigger $t -Principal (New-ScheduledTaskPrincipal -UserID \\\"NT AUTHORITY\\SYSTEM\\\" -LogonType ServiceAccount -RunLevel Highest) -Settings (New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter 00:00:01)";


$t = New-ScheduledTaskTrigger -Once -At (Get-Date).AddHours(24);
Register-ScheduledTask -Force -TaskName $taskName -Action (New-ScheduledTaskAction -Execute C:\test.bat) -Trigger $t -Principal (New-ScheduledTaskPrincipal -UserID \\\"NT AUTHORITY\\SYSTEM\\\" -LogonType ServiceAccount -RunLevel Highest);
Start-ScheduledTask -TaskName $taskName;
Start-Job -ScriptBlock { Start-Sleep -s 10; Unregister-ScheduledTask -Confirm -TaskName 'DelayStartup'";};


Register-ScheduledTask -Force -TaskName $taskName -User '\\ContainerAdmin' -Password 'AutoOps#1' -Action (New-ScheduledTaskAction -Execute C:\test.bat);
Start-ScheduledTask -TaskName $taskName";

A config file for Raspberry Pi 4B with OpenWrt to working as an AP

# cat /etc/config/wireless

config wifi-device 'radio0'
        option type 'mac80211'
        option path 'platform/soc/fe300000.mmcnr/mmc_host/mmc1/mmc1:0001/mmc1:0001:1'
        option hwmode '11a'
        option htmode 'VHT40'
        option channel 'auto'
        option country '00'

config wifi-iface 'wifinet0'
        option ssid 'OpenWrt'
        option encryption 'none'
        option device 'radio0'
        option mode 'ap'
        list maclist 'XX:XX:XX:XX:XX:XX'
        option macfilter 'allow'
        option network 'lan'

An exception about FlexVolume SMB storage plugin

  • 使用了Microsoft的一个FlexVolume SMB插件在Kubernetes Windows容器中挂载SMB存储 microsoft.com~smb.cmd

  • 其中一个节点上的容器偶发性的挂载不上: E1114 09:48:35.398102 4496 driver-call.go:267] Failed to unmarshal output for command: init, output: "RunFlexVolume : \xce\u07b7\xa8\xbd\xab\xa1\xb0RunFlexVolume\xa1\xb1\xcf\xeeʶ\xb1\xf0Ϊ cmdlet\xa1\xa2\xba\xaf\xca\xfd\xa1\xa2\xbdű\xbe\xceļ\xfe\xbb\xf2\xbf\xc9\xd4\xcb\xd0г\xcc\xd0\xf2\xb5\xc4\xc3\xfb\xb3ơ\xa3\xc7\xeb\xbc\xec\xb2\xe9\xc3\xfb\xb3Ƶ\xc4ƴд\xa3\xac\xc8\xe7\xb9\xfb\xb0\xfc\xc0\xa8·\r\n\xbe\xb6\xa3\xac\xc7\xebȷ\xb1\xa3·\xbe\xb6\xd5\xfdȷ\xa3\xacȻ\xba\xf3\xd4\xd9\xca\xd4һ\xb4Ρ\xa3\r\n\xcb\xf9\xd4\xdaλ\xd6\xc3 C:\\usr\\libexec\\kubernetes\\kubelet-plugins\\volume\\exec\\microsoft.com~smb.cmd\\smb.ps1:89 \xd7ַ\xfb: 1\r\n+ RunFlexVolume\r\n+ ~~~~~~~~~~~~~\r\n + CategoryInfo : ObjectNotFound: (RunFlexVolume:String) [], ParentContainsErrorRecordException\r\n + FullyQualifiedErrorId : CommandNotFoundException\r\n \r\n", error: invalid character 'R' looking for beginning of value
    E1114 09:48:35.398102 4496 plugins.go:766] Error dynamically probing plugins: Error creating Flexvolume plugin from directory microsoft.com~smb.cmd, skipping. Error: invalid character 'R' looking for beginning of value

  • Exception内容一堆乱码, cmdlet后的内存去除干扰后感觉像是什么路径不存在: 、函数、骄牺或可运刑序的名常请检查名衬,如果包括径,请保径正,后再试矗所在置

  • 最后发现是C:\usr\libexec\kubernetes\kubelet-plugins\volume\exec\microsoft.com~smb.cmd\flexvolume.ps1的文件内容为空, 不知道为什么DaemonSet没有运行成功. 删除该节点上flexvolume对应的pod后重新挂载,问题解决

Two ways to retrieve process id while startup a process via Windows command line

一个特殊的机缘, 需要通过cmd.exe启动一个进程, 并且获取该启动后进程的Process ID, 搜罗到两种方法:

1. 通过wmic process call create

  • wmic如果创建进程成功,将返回一个ReturnValue为0类JSON结构的输出, 从中获取ProcessId:
C:\app>cmd.exe /C wmic process call create "c:\app\cluster\GatewayServer.exe start -id 6", "c:\app"
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ProcessId = 19420;
        ReturnValue = 0;
};
  • wmic如果创建进程失败, 将返回一个ReturnValue非0的输出:
C:\app>wmic process call create "cluster\GatewayServer.exe start -id 6", "c:\app"
Executing (Win32_Process)->Create()
Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
        ReturnValue = 9;
};

但wmic有一个很大的问题: 不使用当前用户上下文和系统的环境变量.

2. 通过powershell的Start-Process启动进程, 然后取Start-Process返回对像的Id属于得到Process ID:

C:\app>cmd.exe /C powershell -Command "try{$app = Start-Process -PassThru -FilePath \"cluster\GatewayServer.exe\" -WorkingDirectory \"C:\app\" -ArgumentList \"start -id 5\";echo $app.Id} catch {throw}"

Close TCP and UDP ports via windows command line

The CurrPorts tool from Nirsoft can easily close a TCP/UDP connection without kill the Process via Windows command line

cports.exe /close <Local Address> <Local Port> <Remote Address> <Remote Port>

Example:

cports.exe /close 172.24.3.102 51512 172.25.1.206 8007

Download: CurrPorts
Refer: https://superuser.com/questions/384758/how-to-kill-a-particular-tcp-connection-in-windows/384761#384761