Vb.net 是否从WinForm将ExitCode发送到附加的CMD?
我有一个WinForm应用程序,它包括将一种fle格式转换为另一种文件格式 我想添加CLI支持,所以我正在使用WindowsForms中的CMD 如果从CMD调用应用程序,则该CMD将附加到应用程序,并且GUI不会显示 我的应用程序首先检测文件格式 例如,如果我运行此批处理命令,则文件将被删除,因为我没有发送错误代码:Vb.net 是否从WinForm将ExitCode发送到附加的CMD?,vb.net,winforms,cmd,console-application,exit-code,Vb.net,Winforms,Cmd,Console Application,Exit Code,我有一个WinForm应用程序,它包括将一种fle格式转换为另一种文件格式 我想添加CLI支持,所以我正在使用WindowsForms中的CMD 如果从CMD调用应用程序,则该CMD将附加到应用程序,并且GUI不会显示 我的应用程序首先检测文件格式 例如,如果我运行此批处理命令,则文件将被删除,因为我没有发送错误代码: MyApp.exe "File With Incorrec tFormat" && Del "File With Incorrect Format" PS:“&
MyApp.exe "File With Incorrec tFormat" && Del "File With Incorrect Format"
PS:“&&”批处理运算符用于检查before命令的%ERRORLEVEL%是否为“0”,以继续进行命令连接
我想在使用我的应用程序时避免这样的风险
那么,当我的应用程序检测到文件格式不正确时,我如何向附加的CMD发送非零exitcodes
PS:我不知道我需要的是发送一个非零exitcode还是我需要做其他事情
这是程序:
' Parse Arguments
Private Sub Parse_Arguments()
If My.Application.CommandLineArgs.Count <> 0 Then NativeMethods.AttachConsole(-1) Else Exit Sub
Dim File As String = My.Application.CommandLineArgs.Item(0).ToLower
If IO.File.Exists(File) Then
If Not IsRegFile(File) Then
Console.WriteLine("ERROR: " & "" & File & "" & " is not a valid Regedit v5.00 script.")
End
End If
Dim fileinfo As New IO.FileInfo(File)
If My.Application.CommandLineArgs.Count = 1 Then
Try
IO.File.WriteAllText(fileinfo.DirectoryName & ".\" & fileinfo.Name.Substring(0, fileinfo.Name.LastIndexOf(".")) & ".bat", Reg2Bat(File), System.Text.Encoding.Default)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Else
Try
IO.File.WriteAllText(My.Application.CommandLineArgs.Item(1), Reg2Bat(File), System.Text.Encoding.Default)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End If ' My.Application.CommandLineArgs.Count = 1
' Console.WriteLine("Done!")
Else
Console.WriteLine("ERROR: " & "" & File & "" & " don't exists.")
End If ' IO.File.Exists
End
End Sub
分析参数
私有子解析_参数()
如果My.Application.CommandLineArgs.Count为0,则NativeMethods.AttachConsole(-1)否则退出Sub
Dim文件格式为String=My.Application.CommandLineArgs.Item(0).ToLower
如果IO.File.Exists(文件)存在,则
如果不是IsRegFile(文件),则
Console.WriteLine(“错误:&”“文件&”“不是有效的Regedit v5.00脚本。”)
终止
如果结束
将fileinfo设置为新IO.fileinfo(文件)
如果My.Application.CommandLineArgs.Count=1,则
尝试
IO.File.writealText(fileinfo.DirectoryName&“\”&fileinfo.Name.Substring(0,fileinfo.Name.LastIndexOf(“.”)和“.bat”,Reg2Bat(文件),System.Text.Encoding.Default)
特例
控制台写入线(例如消息)
结束尝试
其他的
尝试
IO.File.WriteAllText(My.Application.CommandLineArgs.Item(1)、Reg2Bat(文件)、System.Text.Encoding.Default)
特例
控制台写入线(例如消息)
结束尝试
如果'My.Application.CommandLineArgs.Count=1,则结束
'Console.WriteLine(“完成!”)
其他的
Console.WriteLine(“错误:&”“文件&”“不存在”)
如果“IO.File.exe”存在,则结束
终止
端接头
更新:
另一个更具体的例子是我正在尝试做什么…:
Public Class Form1
<System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError:=True)> _
Private Shared Function AttachConsole(dwProcessId As Int32) As Boolean
End Function
Private Shared Function SendExitCode(ByVal ExitCode As Int32) As Int32
' Here will goes unknown stuff to set the attached console exitcode...
Console.WriteLine(String.Format("Expected ExitCode: {0}", ExitCode))
Return ExitCode
End Function
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
AttachConsole(-1) ' Attaches the console.
SendExitCode(2) ' Send the exitcode (2) to the attached console.
Application.Exit() ' ...And finally close the app.
End Sub
End Class
公共类表单1
_
专用共享函数AttachConsole(dwProcessId为Int32)为布尔值
端函数
私有共享函数SendExitCode(ByVal ExitCode作为Int32)作为Int32
'这里将使用未知内容来设置连接的控制台exitcode。。。
Console.WriteLine(String.Format(“预期的ExitCode:{0}”,ExitCode))
返回退出码
端函数
显示的私有子表单1_(发送方作为对象,e作为事件参数)处理MyBase。显示
AttachConsole(-1)”连接控制台。
SendExitCode(2)'将exitcode(2)发送到连接的控制台。
Application.Exit()“…并最终关闭应用程序。
端接头
末级
如何操作?您需要将应用程序编译为控制台应用程序(即使您有一个GUI,如果没有从命令行调用它,您也可以启动该GUI),并且有一个返回int或call环境的main方法。退出(-1)。您需要将应用程序编译为控制台应用程序(即使您有一个GUI,如果不是从命令行调用,您也可以启动它),并且有一个main方法返回int或call environment.exit(-1)。如果我正确理解了您的问题,下面的代码应该可以做到这一点。您可以从批处理文件调用GUI应用程序,附加到(CMD进程的)父控制台并向其返回退出代码
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestApp
{
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
const uint ATTACH_PARENT_PROCESS = uint.MaxValue;
// The main entry point for the application.
[STAThread]
static int Main(string[] args)
{
if (args.Length < 1)
return 1;
int exitCode = 0;
int.TryParse(args[0], out exitCode);
var message = String.Format("argument: {0}", exitCode);
if (args.Length > 1 && args[1] == "-attach")
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine(message); // do the console output
MessageBox.Show(message); // do the UI
return exitCode;
}
}
}
输出:
argument: 1
exit code: 1
将批处理文件中的“1”更改为“0”,输出为:
argument: 0
success
exit code: 0
希望这有帮助
更新:
在更新的VB代码中,您可能需要在退出应用程序之前设置:
Private Shared Function SendExitCode(ByVal ExitCode As Int32) As Int32
' Here will goes unknown stuff to set the attached console exitcode...
Console.WriteLine(String.Format("Expected ExitCode: {0}", ExitCode))
Environment.ExitCode = ExitCode
Return ExitCode
End Function
如果我正确理解了您的问题,下面的代码应该可以做到。您可以从批处理文件调用GUI应用程序,附加到(CMD进程的)父控制台,并向其返回退出代码
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestApp
{
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
const uint ATTACH_PARENT_PROCESS = uint.MaxValue;
// The main entry point for the application.
[STAThread]
static int Main(string[] args)
{
if (args.Length < 1)
return 1;
int exitCode = 0;
int.TryParse(args[0], out exitCode);
var message = String.Format("argument: {0}", exitCode);
if (args.Length > 1 && args[1] == "-attach")
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine(message); // do the console output
MessageBox.Show(message); // do the UI
return exitCode;
}
}
}
输出:
argument: 1
exit code: 1
将批处理文件中的“1”更改为“0”,输出为:
argument: 0
success
exit code: 0
希望这有帮助
更新:
在更新的VB代码中,您可能需要在退出应用程序之前设置:
Private Shared Function SendExitCode(ByVal ExitCode As Int32) As Int32
' Here will goes unknown stuff to set the attached console exitcode...
Console.WriteLine(String.Format("Expected ExitCode: {0}", ExitCode))
Environment.ExitCode = ExitCode
Return ExitCode
End Function
谢谢你的asnwer,我已经尝试过了,而且很有效,但是正如我所说的,我使用的是windowsForm,如果我编译为“控制台应用程序”然后,当我启动GUI时,会显示一个令人恶心的控制台实例,因此如果您知道如何避免在我从explorer启动应用程序时控制台不会自动连接,那么我将非常感激它…这就是为什么我不编译为控制台应用程序,我希望仅当我从控制台运行程序时才显示控制台,我已尝试使用Freecon唯一的APi函数在开始时从GUI中释放控制台,但什么也不做。感谢asnwer,我已经尝试过了,并且可以工作,但是正如我所说的,如果我编译为“控制台应用程序”,我就在windowsForm上然后,当我启动GUI时,会显示一个令人恶心的控制台实例,因此如果您知道如何避免在我从explorer启动应用程序时控制台不会自动连接,那么我将非常感激它…这就是为什么我不编译为控制台应用程序,我希望仅当我从控制台运行程序时才显示控制台,我已尝试使用Freecon唯一的APi函数在开始时从GUI中释放控制台,但什么也不做。谢谢,但我正在使用VB.NET,我曾尝试使用在线翻译工具翻译它,但我自己在VB上不工作,我不知道你的代码中缺少了什么,你能帮我翻译吗?我已经在更新中发布了我的翻译意图,请参见。C我不会在这里发布格式很好的代码,所以将其附加到我的答案中。最后,我所做的是使用“Environment.Exit()”(not.exitcode),它不需要附加任何控制台,谢谢大家…很高兴您已经解决了这个问题。顺便说一句,如果您不从GUI执行任何控制台输出,您就不必附加到父控制台