基本上有独立过程的应用,都是基于Main作为入口,函数开始运行。在C#中,Main函数可以无参与无返回值,当然也可以有string[]参数和int返回值。WinFrom也符合这一规则。
那么Main作为一个过程的开始函数,谁传输这些参数?然后谁来接受这个返回值呢?显然不可能是过程本身,所以是系统或其他过程。
namespace WinFormDemo01{ internal static class Program{[STAThread]static int Main(string[]args){ MessageBox.Show($"Main方法中收到的参数:{string.Join(',', args)}"); ApplicationConfiguration.Initialize(); Application.Run(new Form1()); return 101; }}}
.NET中,除了在Main该方法也可用于接收参数Enviroment.CommandLine属性和GetCommandLineArgs方法接收,属性会用空格区分多个参数,方法返回值是一个string[],与Main中args不同的是,这里有一条应用程序运行路径。下面的代码是在Form在1窗体中,用按钮显示接收到的按钮Main方法参数。
namespace WinFormDemo01{ public partial class Form1 : Form{ public Form1(){ InitializeComponent(); }private void button1_Click(object sender, EventArgs e){ //MessageBox.Show(Environment.CommandLine); var args = Environment.GetCommandLineArgs(); if (args.Length > 1){ label1.Text = $";主程序:{args[0]},\\r\
\\r\
参数:{string.Join(',', args[1..])}"; }}}}
用批处理调用过程
让我们来看看的用途widnows调用系统bat,实现对Main函数的送参和取回值,比如这个bat名称为result.bat,要求文件和我们的程序在文件夹下启动命令行程序,进入目录并运行rusult.bat即可。
@echo off WinFormDemo01 guisuwei 1234567890@if "%ERRORLEVEL%" == "0" goto ok :fail echo Execution Failed echo return value = %ERRORLEVEL% goto end :ok echo Execution succeeded echo Return value = %ERRORLEVEL% goto end :end
结果如下,可以看到Main中弹框参数
Form1中取Main函数参数
在命令行中收到的返回值为101
用一个过程来调用这个过程
虽然可以实现批处理调用,但使用场景仍然有限,一般来说,我们用一个过程来调用另一个过程,就像一个是主程序,另一个是子程序。
我们用WinFormDemo00来调用WinFormDemo01.这里有两种方法,即阻塞,也称为同步,另一种是非阻塞,或异步。
我们用WinFormDemo00来调用WinFormDemo01.这里有两种方法,即阻塞,也称为同步,另一种是非阻塞,或异步。buton1_click方法是异步,即调动WinFormDemo01后,WinFormDemo00该做什么,不会卡住等待它的返回值。button2_click在这种情况下,它会卡住,直到结果返回。using System.Diagnostics;namespace WinFormDemo00{ public partial class Form1 : Form{ public Form1(){ InitializeComponent(); }private void button1_Click(object sender, EventArgs e){ //WinFormDemo01所在路径 var pro = Process.Start(@"C:\\MyFile\\Asp.NetCoreExperiment\\Asp.NetCoreExperiment\\WinForm\\WinFormDemo01\\bin\\Debug\
et7.0-windows\\WinFormDemo01.exe", new string[]{ "gsw", "abcd" }); //必须使用此属性,事件生效 pro.EnableRaisingEvents = true; pro.Exited = Pro_Exited; }private void Pro_Exited(object? sender, EventArgs e){ ///因为是异常,这种方法所在的线程和UI线程不一样,所以用这种方法来操作UI线程的控件 this.Invoke((object sender) =>{ label1.Text = $"{DateTime.Now},WinFormDemo01返回值:{(sender as Process)?.ExitCode.ToString()}"; }, sender); }private void button2_Click(object sender, EventArgs e){ var pro = Process.Start(@"C:\\MyFile\\Asp.NetCoreExperiment\\Asp.NetCoreExperiment\\WinForm\\WinFormDemo01\\bin\\Debug\
et7.0-windows\\WinFormDemo01.exe", new string[]{ "gsw", "abcd" }); //阻塞 pro.WaitForExit(); label1.Text = $"{DateTime.Now},WinFormDemo01返回值: ro.ExitCode.ToString()}"; }}}