在Windows Server 2003版本中,IIS里面好像没有默认的FacstCGI组件,所以需要下载一个独立的FastCGI版本进行安装;不过在WIndows Server 2008以上版本在IIS中就已经自带了FastCGI的组件了,如果自行下载 fcgisetup_1.5_rtw_x64.msi (官网:IIS 5.1,IIS 6,IIS 7)或其他版本来进行独立安装,那是无法安装的,提示FastCGI版本和IIS版本的不支持,“Setup was unable to detect a supported version of IIS install. If you platform is x64, you wil need to install FastCGI x64.”; WIndows Server 2008以上版本在IIS中默认安装IIS时是没有被安装的,所以只需要去命令行安装它就可以了(我是这么做的)。经过查看官方文档,然后自己总结整理了出代码,在cmd命令行下操作,代码如下:
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <Shlwapi.h>
#include "process.h"
#pragma comment(lib, "Shlwapi.lib")
using namespace std;
BOOL IsWow64();
bool RunSysCmd(const wstring& lpstrCmd, const wstring& wstrcmd);
bool SetupFastCGI(const wstring& instPath);
int _tmain(int argc, _TCHAR* argv[])
{
bool bRet = false;
bRet = SetupFastCGI(_T("E:\\mywww\\server\\php\\5.6"));
system("pause");
return 0;
}
bool SetupFastCGI(const wstring& instPath)
{
bool bRet = false;
if (instPath.empty())
{
return bRet;
}
wstring cmdRoot;
if (IsWow64())
{
cmdRoot = _T("C:\\Windows\\SysWOW64\\inetsrv");
}
else
cmdRoot = _T("C:\\Windows\\System32\\inetsrv");
wstring phpcgi = instPath + _T("\\php-cgi.exe");
wstring phpini = instPath + _T("\\php.ini");
wstring fastCGI = _T("");
fastCGI.append(cmdRoot);
fastCGI.append(_T("\\appcmd.exe set config -section:system.webServer/fastCgi /+\"[fullPath='"));
fastCGI.append(phpcgi);
fastCGI.append(_T("',MonitorChangesTo='"));
fastCGI.append(phpini);
fastCGI.append(_T("',instanceMaxRequests='10000']\" /commit:apphost"));
fastCGI.append(_T("\r\n"));
wstring envVariable = _T("");
envVariable.append(cmdRoot);
envVariable.append(_T("\\appcmd.exe set config -section:system.webServer/fastCgi /+\"[fullPath='"));
envVariable.append(phpcgi);
envVariable.append(_T("'].environmentVariables.[name='PHP_FCGI_MAX_REQUESTS',value='10000']\" /commit:apphost"));
envVariable.append(_T("\r\n"));
wstring handlers = _T("");;
handlers.append(cmdRoot);
handlers.append(_T("\\appcmd.exe set config -section:system.webServer/handlers /+\"[name='PHP_ny_FastCGI',path='*.php',verb='*',modules='FastCgiModule',scriptProcessor='"));
handlers.append(phpcgi);
handlers.append(_T("',resourceType='Unspecified',requireAccess='Script']\" /commit:apphost"));
handlers.append(_T("\r\n"));
wstring filephp = _T("");;
wstring filephpName = _T("weishao.php");
filephp.append(cmdRoot);
filephp.append(_T("\\appcmd.exe set config -section:system.webServer/defaultDocument /+\"files.[value='"));
filephp.append(filephpName);
filephp.append(_T("']\" /commit:apphost"));
filephp.append(_T("\r\n"));
wstring echo;
wstring exits;
wstring datacmd;
echo = _T("@echo off\r\n");
exits = _T("\r\n@exit");
datacmd = echo + fastCGI + envVariable + handlers + filephp + exits;
//使用脚本.bat脚本的方式执行
wstring installbat;
installbat = _T("C:\\install.bat"); // 临时文件
if (!::PathFileExists(installbat.c_str()))
{
HANDLE hFile = (HANDLE)::CreateFile(installbat.c_str(), GENERIC_WRITE | GENERIC_READ, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
::CloseHandle(hFile);
}
}
HANDLE hFile = (HANDLE)::CreateFile(installbat.c_str(), GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
DWORD dwLen = 0;
DWORD dwBytesWrite = 0;
char* pBuffer = NULL;
dwLen = ::WideCharToMultiByte(CP_ACP, NULL, datacmd.c_str(), -1, NULL, NULL, NULL, FALSE);
pBuffer = new char[dwLen];
if (!pBuffer) return FALSE;
::WideCharToMultiByte(CP_ACP, NULL, datacmd.c_str(), -1, pBuffer, dwLen, NULL, FALSE);
bRet = ::WriteFile(hFile, pBuffer, strlen(pBuffer), &dwBytesWrite, NULL);
if (!bRet)
{
std::cout << _T("install.bat文件生成失败.") << endl;
}
delete[] pBuffer;
pBuffer = NULL;
::CloseHandle(hFile);
}
if (RunSysCmd(installbat.c_str(), _T("")))
{
bRet = TRUE;
}
if (::PathFileExists(installbat.c_str()))
{
::DeleteFile(installbat.c_str());
}
return bRet;
}
BOOL IsWow64()
{
typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;
BOOL bIsWow64 = FALSE;
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process");
if (NULL != fnIsWow64Process){
fnIsWow64Process(GetCurrentProcess(), &bIsWow64);
}
return bIsWow64;
}
bool RunSysCmd(const wstring& lpstrCmd, const wstring& wstrcmd)
{
bool bRet = false;
if (lpstrCmd.length() == 0)
{
return bRet;
}
wstring stdDirectory = getSystemDirectory()/* + _T("Windows\\System32\\")*/;
if (IsWow64())
{
PVOID OldValue = NULL;
Wow64DisableWow64FsRedirection(&OldValue);
SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = _T("runas");
ShExecInfo.lpFile = lpstrCmd.c_str();
ShExecInfo.lpParameters = wstrcmd.c_str();
ShExecInfo.lpDirectory = stdDirectory.c_str();
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
bRet = ShellExecuteEx(&ShExecInfo);
if (!bRet)
{
return FALSE;
}
if (WaitForSingleObject(ShExecInfo.hProcess, 10000) == WAIT_TIMEOUT)
{
TerminateProcess(ShExecInfo.hProcess, 0);
std::cout << _T("fastcgi cmd Process step timeout.") << endl;
return FALSE;
}
Wow64RevertWow64FsRedirection(OldValue);
}
else
{
SHELLEXECUTEINFO ShExecInfo = { 0 };
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = _T("runas");
ShExecInfo.lpFile = lpstrCmd.c_str();
ShExecInfo.lpParameters = wstrcmd.c_str();
ShExecInfo.lpDirectory = stdDirectory.c_str();
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
bRet = ShellExecuteEx(&ShExecInfo);
if (!bRet)
{
return FALSE;
}
if (WaitForSingleObject(ShExecInfo.hProcess, 10000) == WAIT_TIMEOUT)
{
// 强行杀死进程
TerminateProcess(ShExecInfo.hProcess, 0);
std::cout << _T("fastcgi cmd Process step timeout.") << endl;
return FALSE;
}
}
return bRet;
}
以上是我个的安装方式,供参考,有不足之处还望大家点评。当然大家有更好的解决方案,可以给我留言,大家相互学习。