2

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?.

4

2 回答 2

2

如果我正确理解了您的问题,则应该使用以下代码。您可以从批处理文件调用 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;
        }
    }
}

这是一个测试批处理文件:

@echo off
TestApp.exe 1 -attach && echo success
echo exit code: %errorlevel%

输出:

argument: 1
exit code: 1

在批处理文件中将“1”更改为“0”,输出将是:

argument: 0
success
exit code: 0

希望这可以帮助。

更新:

在您更新的 VB 代码中,您可能需要在退出应用程序之前设置Environment.ExitCode :

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
于 2013-08-04T07:51:20.217 回答
2

您需要将您的应用程序编译为控制台应用程序(即使您有一个如果没有从命令行调用就启动的 GUI)并且有一个返回 int 或调用 environment.exit(-1) 的 main 方法。

于 2013-07-26T04:32:58.423 回答