1

プログラムでいくつかのCMDコマンドを使用しますが、これらのコマンドはいくつかの例外をスローする可能性があります。ご存知のように、例外が発生すると、CMDは独自のエラーメッセージを画面に書き込みます。しかし、私は自分自身のエラーメッセージを書きたいと思います。

私の質問はこれです:CMDメッセージをブロックして自分のエラーメッセージだけを書く方法はありますか?

PSこれは複雑なプログラムではありません。System()を使用してCMDコマンドを実行します。

例:

たとえば、ユーザーはプログラム内の任意のファイルの名前を変更してコピーできます。ご存知のように、ユーザーがファイルのパスを正しく入力しないと、画面にエラーメッセージが表示されます。そして、このエラーメッセージが画面に表示されないようにしたいと思います。私自身のエラーメッセージのみが表示されます。

ありがとうございました!

4

5 に答える 5

3

プラットフォームと使用するコマンドによって異なります。ちなみに、コンソールコマンドを呼び出すための使用はsystem()、ほとんどの人に強く推奨されていません(ほとんどの目的で重くなります)。
CREATE_NO_WINDOWフラグを使用して使用し、とCreateProcess()の呼び出しでプロセスが終了するのを待つことをお勧めします。 このアプローチは、ほとんどのCMDコマンドがのどこかにある実行可能ファイルであるという事実を利用しています。WaitForSingleObject()GetExitCodeProcess()
C:/Windows/...

/*
 * Executes a program and returns it's exit code.
 *
 * TODO: Error checking should be added for
 *   CreateProcess()
 *   WaitForSingleObject()
 *   GetExitCodeProcess()
 */
DWORD ExecCmdLine(TCHAR const* cmdline)
{
    STARTUPINFO si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi;
    memset(&pi, 0, sizeof(pi));
    ::CreateProcess(NULL, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
    ::CloseHandle(pi.Thread);
    ::WaitForSingleObject(pi.hProcess, INFINITE);
    DWORD exitcode;
    ::GetExitCodeProcess(pi.hProcess, &exitcode);
    ::CloseHandle(pi.hProcess);
    return exitcode;
}

コマンドの出力を取得する場合は、構造体に、を指定して、に設定hStdOutputすることもできます。コマンドの実行中に(特にファイルのコピーについて述べたように)、独自のプログラムで他のことを実行することもできます。これはC++の方法で行われます。hStdErrorSTARTUPINFOSTARTF_USESTDHANDLESSTARTUPINFO.dwFlags

/*
 * TODO: Error checking should be added for
 *   CreateProcess()
 *   WaitForSingleObject()
 *   GetExitCodeProcess()
 */
class AsyncCmd
{
public:
    AsyncCmd(std::string const& cmdline)
        : cmdline(cmdline),
          processHandle(NULL)
    {
    }
    ~AsyncCmd()
    {
        if (this->processHandle != NULL)
            ::CloseHandle(this->processHandle);
    }
    // Starts the execution of the commandline.
    void Start(HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE), HANDLE hErr = GetStdHandle(STD_ERROR_HANDLE))
    {
        STARTUPINFO si;
        memset(&si, 0, sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        si.hStdOutput = hOut;
        si.hStdError = hErr;
        PROCESS_INFORMATION pi;
        memset(&pi, 0, sizeof(pi));
        ::CreateProcess(NULL, this->cmdline.c_str(), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
        ::CloseHandle(pi.hThread);
        this->processHandle = pi.hProcess;
    }
    // Blocks until execution is finished and returns the exit code.
    DWORD ExitCode()
    {
        ::WaitForSingleObject(this->processHandle, INFINITE);
        DWORD exitcode;
        ::GetExitCodeProcess(this->processHandle, &exitcode);
        return exitcode;
    }
private:
    AsyncCmd(AsyncCmd const&);
    AsyncCmd& operator=(AsyncCmd const&);
    std::string cmdline;
    HANDLE processHandle;
}
于 2012-11-16T22:56:42.713 に答える
1

すでに言われていることを言い換えると:

Q:「system()」を介して呼び出したコマンドによってスローされたエラーをなんとかして傍受できますか?

A:いいえ。多くの理由があります。

ただし、コマンドラインプログラムによって書き込まれたテキストエラーメッセージをリダイレクトすることはできます。

  • 「stderr」のリダイレクトは比較的簡単です。「GetStdHandle(STD_ERROR_HANDLE)」は1つの方法です。">:err"へのリダイレクトは別です。

  • 残念ながら、すべてのプログラムが「stderr」にエラーメッセージを書き込むのに十分なほど優れているわけではありません。

    多くの人がすべてを「stdout」に書き込みます。

後者の場合、1)実際にエラーが発生したこと、および2)「標準出力」であるテキスト入力の部分と「エラーテキスト」である部分を分離する方法を理解する必要があります。 。

PS:

「system()」の代替APIは「popen()」です。

于 2012-11-16T23:48:35.073 に答える
0

これを行うブルートフォース攻撃の1つの方法は、CMDの出力をファイルにパイプ処理してyourCommand > file.txtから、ファイルの内容を読み取って例外が発生したかどうかを判断することです。

于 2012-11-16T22:40:41.327 に答える
0

yourmtが書いたことに加えて、例外がプロセスの境界を越えてブリードスルーしないことを指摘したいと思います。したがって、ここで取り組んでいるのは、実行されたプログラム(およびシェル)の出力(stderrとの両方)とその終了コード(これが有用な情報を提供する場合)です。stdoutこれは主に、タイトルが示すように、これは文字通り例外処理に関するものではないことを理解するためです。

つまり、 /を使用するときに、制御するパイプと出力を「キャッチ」する場所を設定hStdOutputし、それをコンソールに出力する前に独自のパイプに置き換えることができます。交換するだけの場合は、交換することもできます。hStdErrorCreateProcessCreateProcessExstderr

于 2012-11-16T23:42:59.057 に答える
-1

使用できます

#include "Exception.h"

class MyClass
{
public:
    class Error : public Exception { };
    MyClass();
    ~MyClass();
    void myFunction() throw(Error);
}

..。

catch (MyClass::Error & error)
{
    cout << error.full_message << endl;

    return;
}

class Exception
{
public:
    std::string message;
    std::string full_message;

    virtual char * info() { return ""; };

    void setMessage(std::string msg)
    {
        message = msg;
        if (*info() == 0) { full_message = msg; }
        else { full_message = MakeString() << info() << " " << msg; }
    }
};

// template function ///////////////////////////////////////////

template <class errType>
void Throw(const std::string msg=std::string(""))
{
errType err;
err.setMessage(msg);

throw(err);
}
于 2012-11-16T22:47:51.163 に答える