Reputation: 20474
I have a WinForm application wich consists in convert one fle format to other file format.
I wanted to add CLI support so I'm working the CMD from the WindowsForms.
If the application is called from the CMD then that CMD is attached to the APP and the GUI is not displayed.
My application detects the file format firsts of do nothing.
The problem is for example if I run this Batch command then the file will be deleted because I'm not sending an errorcode:
MyApp.exe "File With Incorrec tFormat" && Del "File With Incorrect Format"
PS: The "&&" Batch operator is used to check if the %ERRORLEVEL% of the before command is "0" to continue with the command concatenation.
I want to avoid risks as that when using my app.
Then how I can send a non-zero exitcodes to the attached CMD when my app detects the file format is not correct?
PS: I don't know if what I need is to send a non-zero exitcode or I need to do other thing.
This is the proc:
' 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
UPDATE:
Another example more expecific of what I'm trying to do...:
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
How I can do it?.
Upvotes: 2
Views: 1260
Reputation: 61716
If I understood your question correctly, the following code should do it. You can invoke a GUI app from a batch file, attach to the parent console (of the CMD process) and return an exit code to it.
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;
}
}
}
Here is a test batch file:
@echo off
TestApp.exe 1 -attach && echo success
echo exit code: %errorlevel%
The output:
argument: 1
exit code: 1
Change "1" to "0" in the batch file, and the output will be:
argument: 0
success
exit code: 0
Hope this helps.
UPDATE:
In your updated VB code, you probably need to set Environment.ExitCode before exiting the app:
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
Upvotes: 2
Reputation: 13571
You need to compile your app as a console app (even if you have a GUI that you start if not called from the command line) and either have a main method that returns an int or call environment.exit(-1).
Upvotes: 2