using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Diagnostics;
using
System.Drawing;
using
System.IO;
using
System.Text;
using
System.Threading;
using
System.Windows.Forms;
using
Microsoft.Win32;
namespace
IISTuner
{
public
partial
class
Form1 : Form
{
public
Form1()
{
InitializeComponent();
}
internal
string
[] SetRegistryEntry(Dictionary<
string
,
int
> entries)
{
List<
string
> cmds =
new
List<
string
>();
foreach
(
string
k
in
entries.Keys)
{
string
position = k.Split(
':'
)[0];
string
parameter = k.Split(
':'
)[1];
int
value = Convert.ToInt32(entries[k]);
cmds.Add(
"reg add HKLM\\"
+ position +
" /v "
+ parameter +
" /t REG_DWORD /d "
+ value.ToString() +
" /f"
);
}
return
cmds.ToArray();
}
internal
void
Tune()
{
Dictionary<
string
,
int
> cmds =
new
Dictionary<
string
,
int
>();
cmds.Add(
"System\\CurrentControlSet\\Services\\HTTP\\Parameters:EnableAggressiveMemoryUsage"
, 1);
cmds.Add(
"System\\CurrentControlSet\\Services\\HTTP\\Parameters:EnableCopySend"
, 1);
cmds.Add(
"System\\CurrentControlSet\\Services\\TcpIp\\Parameters:TcpTimedWaitDelay"
, 30);
cmds.Add(
"System\\CurrentControlSet\\Services\\HTTP\\Parameters:MaxConnections"
, 65535);
if
(Loading.Net2Exist)
{
cmds.Add(
"SOFTWARE\\Microsoft\\ASP.NET\\2.0.50727.0:MaxConcurrentRequestsPerCPU"
, 0);
cmds.Add(
"SOFTWARE\\Microsoft\\ASP.NET\\2.0.50727.0:MaxConcurrentThreadsPerCPU"
, 0);
}
if
(Loading.Net4Exist)
{
cmds.Add(
"SOFTWARE\\Microsoft\\ASP.NET\\4.0.30319.0:MaxConcurrentRequestsPerCPU"
, 0);
cmds.Add(
"SOFTWARE\\Microsoft\\ASP.NET\\4.0.30319.0:MaxConcurrentThreadsPerCPU"
, 0);
}
string
[] cmd = SetRegistryEntry(cmds);
RunMSDOS(cmd);
}
internal
void
CreateIIS7Pool()
{
RunMSDOS(
new
string
[]{
Loading.InetDir +
"\\appcmd stop apppool PokeIn"
,
Loading.InetDir +
"\\appcmd add apppool /name:PokeIn /managedPipelineMode:Integrated"
,
Loading.InetDir +
"\\appcmd set apppool PokeIn /queueLength:65535"
,
Loading.InetDir +
"\\appcmd set config /section:processModel /autoConfig:false /commit:MACHINE"
,
Loading.InetDir +
"\\appcmd set apppool PokeIn /autoStart:true"
,
Loading.InetDir +
"\\appcmd set apppool PokeIn /enable32BitAppOnWin64:true"
,
Loading.InetDir +
"\\appcmd set apppool PokeIn /startMode:AlwaysRunning"
,
Loading.InetDir +
"\\appcmd set apppool PokeIn /processModel.shutdownTimeLimit:110"
,
Loading.InetDir +
"\\appcmd set config /section:processModel /maxWorkerThreads:100 /commit:MACHINE"
,
Loading.InetDir +
"\\appcmd set config /section:processModel /maxIoThreads:100 /commit:MACHINE"
,
Loading.InetDir +
"\\appcmd set config /section:processModel /minWorkerThreads:100 /commit:MACHINE"
,
Loading.InetDir +
"\\appcmd set config /section:processModel /requestQueueLimit:Infinite /commit:MACHINE"
,
Loading.InetDir +
"\\appcmd set config /section:serverRuntime /appConcurrentRequestLimit:65535"
,
Loading.InetDir +
"\\appcmd start apppool PokeIn"
});
}
bool
_processWorking =
false
;
internal
void
RunMSDOS(
string
[] cmds)
{
if
(_processWorking)
return
;
btnTune.Enabled =
false
;
_processWorking =
true
;
ProcessStartInfo psi =
new
ProcessStartInfo(
"cmd.exe"
)
{
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow =
true
,
RedirectStandardError =
true
,
RedirectStandardInput =
true
,
RedirectStandardOutput =
true
,
UseShellExecute =
false
};
Process msdos =
new
Process { StartInfo = psi, EnableRaisingEvents =
true
};
msdos.Exited +=
new
EventHandler(MSDOSExited);
msdos.Start();
foreach
(
string
cmd
in
cmds)
msdos.StandardInput.WriteLine(cmd);
msdos.StandardInput.WriteLine(
"exit"
);
WaitMSDOS();
btnTune.Enabled =
true
;
}
internal
void
WaitMSDOS()
{
while
(
true
)
{
if
(!_processWorking)
break
;
Thread.Sleep(100);
Application.DoEvents();
}
}
void
MSDOSExited(
object
sender, EventArgs e)
{
_processWorking =
false
;
}
static
bool
TuneMachineConfig()
{
List<
string
> frameworks =
new
List<
string
>();
if
(Loading.Net2Exist) frameworks.Add(Loading.Net2Dir +
"\\Config\\"
);
if
(Loading.Net4Exist) frameworks.Add(Loading.Net4Dir +
"\\Config\\"
);
if
(Loading.Net264Exist) frameworks.Add(Loading.Net264Dir +
"\\Config\\"
);
if
(Loading.Net464Exist) frameworks.Add(Loading.Net464Dir +
"\\Config\\"
);
foreach
(
string
dir
in
frameworks)
{
try
{
File.Copy(dir +
"machine.config"
, dir +
"machine.config.bak."
+ DateTime.Now.ToFileTimeUtc().ToString());
}
catch
{
MessageBox.Show(Loading.AdminMessage);
return
false
;
}
StreamReader rd =
new
StreamReader(dir +
"machine.config"
, Encoding.Default);
string
config = rd.ReadToEnd();
rd.Close();
int
posweb = config.IndexOf(
"<system.web>"
);
if
(posweb > 0)
{
posweb = config.IndexOf(
"<processModel"
, posweb);
int
endpos = config.IndexOf(
"/>"
, posweb);
string
left = config.Substring(0, posweb);
string
right = config.Substring(endpos + 2, config.Length - (endpos + 2));
config = left
+
"<processModel autoConfig=\"true\" minIoThreads=\"30\" maxWorkerThreads=\"100\" maxIoThreads=\"100\" minWorkerThreads=\"100\" requestQueueLimit=\"Infinite\" />"
+ right;
StreamWriter wr =
new
StreamWriter(dir +
"machine.config"
,
false
);
wr.Write(config);
wr.Close();
}
}
frameworks.Clear();
return
true
;
}
static
bool
TuneASPNETConfig()
{
List<
string
> frameworks =
new
List<
string
>();
if
(Loading.Net2Exist) frameworks.Add(Loading.Net2Dir +
"\\"
);
if
(Loading.Net4Exist) frameworks.Add(Loading.Net4Dir +
"\\"
);
if
(Loading.Net264Exist) frameworks.Add(Loading.Net264Dir +
"\\"
);
if
(Loading.Net464Exist) frameworks.Add(Loading.Net464Dir +
"\\"
);
foreach
(
string
dir
in
frameworks)
{
try
{
File.Copy(dir +
"Aspnet.config"
, dir +
"Aspnet.config.bak."
+ DateTime.Now.ToFileTimeUtc().ToString());
}
catch
{
MessageBox.Show(Loading.AdminMessage);
return
false
;
}
StreamReader rd =
new
StreamReader(dir +
"Aspnet.config"
, Encoding.Default);
string
config = rd.ReadToEnd();
rd.Close();
bool
found = config.Contains(
"</configuration>"
);
found = found && !config.Contains(
"maxConcurrentRequestsPerCPU"
);
if
(found)
{
if
(!config.Contains(
"</system.web>"
))
config = config.Replace(
"</configuration>"
,
"<system.web><applicationPool maxConcurrentRequestsPerCPU=\"5000\" maxConcurrentThreadsPerCPU=\"0\" requestQueueLimit=\"25000\" /></system.web></configuration>"
);
else
config = config.Replace(
"</system.web>"
,
"<applicationPool maxConcurrentRequestsPerCPU=\"5000\" maxConcurrentThreadsPerCPU=\"0\" requestQueueLimit=\"25000\" /></system.web>"
);
StreamWriter wr =
new
StreamWriter(dir +
"Aspnet.config"
,
false
);
wr.Write(config);
wr.Close();
}
}
frameworks.Clear();
return
true
;
}
/// <summary>
/// 优化IIS
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private
void
BtnTuneClick(
object
sender, EventArgs e)
{
if
(!TuneMachineConfig() || !TuneASPNETConfig())
{
this
.Close();
return
;
}
string
iisNotes;
if
(Loading.IISVersion == 7)
{
CreateIIS7Pool();
iisNotes =
"Optimized IIS Application pool PokeIn is created.\nPlease move your web application onto PokeIn app. pool on IIS to receive optimization benefits."
;
}
else
{
iisNotes =
"Open properties page of your IIS6 application pool and remove 'request que limit'"
;
}
Tune();
MessageBox.Show(
"You environment is optimized for performance!\nTCP, HTTP, ASP.NET Registry settings optimized.\nMachine.config file optimized and backed up\n\n"
+ iisNotes +
"\n\nYou must restart this computer to activate the changes."
,
"READ CAREFULLY!"
);
}
private
void
LinkLabel1LinkClicked(
object
sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(
"http://www.tywh.com"
);
}
}
}