C++/CLI第二版——重定向了stdin,并可指定编码格式
// CmdHelper.h
#pragma once
#include <vcclr.h>
#include <windows.h>
#pragma comment(lib, "kernel32.lib")
using namespace System;
using namespace System::IO;
using namespace System::Text;
using namespace System::Runtime::InteropServices;
using namespace System::ComponentModel;
namespace CmdHelper {
public ref class Cmd
{
public:
Cmd()
{
}
static String^ RunCmd(String^ cmd, String^ instr, Encoding^ enc)
{
String ^tmpin = Path::GetTempFileName();
pin_ptr<const wchar_t> p_tmpin = PtrToStringChars(tmpin);
array<unsigned char> ^inbytes = enc->GetBytes(instr);
File::WriteAllBytes(tmpin, inbytes);
String ^tmpname = Path::GetTempFileName();
pin_ptr<const wchar_t> p_tmpname = PtrToStringChars(tmpname);
SECURITY_ATTRIBUTES sa = { sizeof sa };
sa.bInheritHandle = TRUE;
HANDLE inhandle = CreateFile(p_tmpin, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (inhandle == INVALID_HANDLE_VALUE)
{
throw gcnew Win32Exception(GetLastError());
}
HANDLE outhandle = CreateFile(p_tmpname, GENERIC_WRITE, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (outhandle == INVALID_HANDLE_VALUE)
{
DWORD errcode = GetLastError();
CloseHandle(inhandle);
throw gcnew Win32Exception(errcode);
}
HANDLE outhandle2 = INVALID_HANDLE_VALUE;
if (!DuplicateHandle(GetCurrentProcess(), outhandle, GetCurrentProcess(), &outhandle2, 0, TRUE, DUPLICATE_SAME_ACCESS))
{
DWORD errcode = GetLastError();
CloseHandle(inhandle);
CloseHandle(outhandle);
throw gcnew Win32Exception(errcode);
}
WCHAR *p_cmd = (WCHAR *)Marshal::StringToHGlobalUni(cmd).ToPointer();
STARTUPINFO si = { sizeof si };
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = inhandle;
si.hStdOutput = outhandle;
si.hStdError = outhandle2;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi = { 0 };
if (!CreateProcess(NULL, p_cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
DWORD errcode = GetLastError();
CloseHandle(inhandle);
CloseHandle(outhandle);
CloseHandle(outhandle2);
Marshal::FreeHGlobal(IntPtr(p_cmd));
throw gcnew Win32Exception(errcode);
}
Marshal::FreeHGlobal(IntPtr(p_cmd));
CloseHandle(pi.hThread);
CloseHandle(inhandle);
CloseHandle(outhandle);
CloseHandle(outhandle2);
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED)
{
DWORD errcode = GetLastError();
CloseHandle(pi.hProcess);
throw gcnew Win32Exception(errcode);
}
CloseHandle(pi.hProcess);
array<unsigned char> ^outbytes = File::ReadAllBytes(tmpname);
String ^outstr = enc->GetString(outbytes);
File::Delete(tmpin);
File::Delete(tmpname);
return outstr;
}
};
}
</unsigned></const></unsigned></const></windows.h></vcclr.h>