C++/CLI版本(使用时需要#include "Cmd.h")
Cmd.cpp:
#include "StdAfx.h"
#include "Cmd.h"
Cmd.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;
public ref class Cmd
{
public:
Cmd()
{
}
static String^ RunCmd(String^ cmd)
{
String ^tmpname = Path::GetTempFileName();
pin_ptr<const wchar_t> p_tmpname = PtrToStringChars(tmpname);
SECURITY_ATTRIBUTES sa = { sizeof sa };
sa.bInheritHandle = TRUE;
HANDLE outhandle = CreateFile(p_tmpname, GENERIC_WRITE, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (outhandle == INVALID_HANDLE_VALUE)
{
throw gcnew Win32Exception(GetLastError());
}
HANDLE outhandle2 = INVALID_HANDLE_VALUE;
if (!DuplicateHandle(GetCurrentProcess(), outhandle, GetCurrentProcess(), &outhandle2, 0, TRUE, DUPLICATE_SAME_ACCESS))
{
DWORD errcode = GetLastError();
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 = INVALID_HANDLE_VALUE;
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(outhandle);
CloseHandle(outhandle2);
Marshal::FreeHGlobal(IntPtr(p_cmd));
throw gcnew Win32Exception();
}
Marshal::FreeHGlobal(IntPtr(p_cmd));
CloseHandle(pi.hThread);
CloseHandle(outhandle);
CloseHandle(outhandle2);
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED)
{
DWORD errcode = GetLastError();
CloseHandle(pi.hProcess);
throw gcnew Win32Exception(errcode);
}
CloseHandle(pi.hProcess);
String ^outstr = File::ReadAllText(tmpname, Encoding::Default);
File::Delete(tmpname);
return outstr;
}
};
</const></windows.h></vcclr.h>