ElektroStudios
ElektroStudios

Reputation: 20474

Send ExitCode to an attached CMD from a WinForm?

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

Answers (2)

noseratio
noseratio

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

jmoreno
jmoreno

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

Related Questions