早上的时候接到主管的一个任务,要获取服务器上的cpu,硬盘, 数据库等 的使用情况,并以邮件的方式发给boss, = =没办法,公司的服务器真是不敢恭维,顺便吐槽一下公司的网速,卡的时候30k左右徘徊,这不是在浪费我们的时间吗!!!

话不多说上代码,因为是实习,主管还是挺关照我的,一早就给我发了个类库(里面涉及到要查询本机信息的都有).这样我剩下了一大半的时间,

这个功能总的来说就两步:  一,先获取本机的信息    二,发送邮件。

获取本机信息用到的类库 SystemInfo.cs 和 DiskInfo.cs

SystemInfo.cs

 //程序开发:lc_mtt
//CSDN博客:http://lemony.cnblogs.com
//个人主页:http://www.3lsoft.com
//注:此代码禁止用于商业用途。有修改者发我一份,谢谢!
//---------------- 开源世界,你我更进步 ---------------- using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Text;
using System.Management;
using System.Runtime.InteropServices; namespace Lemony.SystemInfo
{
/// <summary>
/// 系统信息类 - 获取CPU、内存、磁盘、进程信息
/// </summary>
public class SystemInfo
{
private int m_ProcessorCount = ; //CPU个数
private PerformanceCounter pcCpuLoad; //CPU计数器
private long m_PhysicalMemory = ; //物理内存 private const int GW_HWNDFIRST = ;
private const int GW_HWNDNEXT = ;
private const int GWL_STYLE = (-);
private const int WS_VISIBLE = ;
private const int WS_BORDER = ; #region AIP声明
[DllImport("IpHlpApi.dll")]
extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder); [DllImport("User32")]
private extern static int GetWindow(int hWnd, int wCmd); [DllImport("User32")]
private extern static int GetWindowLongA(int hWnd, int wIndx); [DllImport("user32.dll")]
private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize); [DllImport("user32", CharSet = CharSet.Auto)]
private extern static int GetWindowTextLength(IntPtr hWnd);
#endregion #region 构造函数
/// <summary>
/// 构造函数,初始化计数器等
/// </summary>
public SystemInfo()
{
//初始化CPU计数器
pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total");
pcCpuLoad.MachineName = ".";
pcCpuLoad.NextValue(); //CPU个数
m_ProcessorCount = Environment.ProcessorCount; //获得物理内存
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (mo["TotalPhysicalMemory"] != null)
{
m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString());
}
}
}
#endregion #region CPU个数
/// <summary>
/// 获取CPU个数
/// </summary>
public int ProcessorCount
{
get
{
return m_ProcessorCount;
}
}
#endregion #region CPU占用率
/// <summary>
/// 获取CPU占用率
/// </summary>
public float CpuLoad
{
get
{
return pcCpuLoad.NextValue();
}
}
#endregion #region 可用内存
/// <summary>
/// 获取可用内存
/// </summary>
public long MemoryAvailable
{
get
{
long availablebytes = ;
//ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win64_PerfRawData_PerfOS_Memory");
//foreach (ManagementObject mo in mos.Get())
//{
// availablebytes = long.Parse(mo["Availablebytes"].ToString());
//}
ManagementClass mos = new ManagementClass("Win32_OperatingSystem");
foreach (ManagementObject mo in mos.GetInstances())
{
if (mo["FreePhysicalMemory"] != null)
{
availablebytes = * long.Parse(mo["FreePhysicalMemory"].ToString());
}
}
return availablebytes;
}
}
#endregion #region 物理内存
/// <summary>
/// 获取物理内存
/// </summary>
public long PhysicalMemory
{
get
{
return m_PhysicalMemory;
}
}
#endregion #region 获得分区信息
/// <summary>
/// 获取分区信息
/// </summary>
public List<DiskInfo> GetLogicalDrives()
{
List<DiskInfo> drives = new List<DiskInfo>();
ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk");
ManagementObjectCollection disks = diskClass.GetInstances();
foreach (ManagementObject disk in disks)
{
// DriveType.Fixed 为固定磁盘(硬盘)
if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed)
{
drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString())));
}
}
return drives;
}
/// <summary>
/// 获取特定分区信息
/// </summary>
/// <param name="DriverID">盘符</param>
public List<DiskInfo> GetLogicalDrives(char DriverID)
{
List<DiskInfo> drives = new List<DiskInfo>();
WqlObjectQuery wmiquery = new WqlObjectQuery("SELECT * FROM Win64_LogicalDisk WHERE DeviceID = '" + DriverID + ":'");
ManagementObjectSearcher wmifind = new ManagementObjectSearcher(wmiquery);
foreach (ManagementObject disk in wmifind.Get())
{
if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed)
{
drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString())));
}
}
return drives;
}
#endregion #region 获得进程列表
/// <summary>
/// 获得进程列表
/// </summary>
public List<ProcessInfo> GetProcessInfo()
{
List<ProcessInfo> pInfo = new List<ProcessInfo>();
Process[] processes = Process.GetProcesses();
foreach (Process instance in processes)
{
try
{
pInfo.Add(new ProcessInfo(instance.Id,
instance.ProcessName,
instance.TotalProcessorTime.TotalMilliseconds,
instance.WorkingSet64,
instance.MainModule.FileName));
}
catch { }
}
return pInfo;
}
/// <summary>
/// 获得特定进程信息
/// </summary>
/// <param name="ProcessName">进程名称</param>
public List<ProcessInfo> GetProcessInfo(string ProcessName)
{
List<ProcessInfo> pInfo = new List<ProcessInfo>();
Process[] processes = Process.GetProcessesByName(ProcessName);
foreach (Process instance in processes)
{
try
{
pInfo.Add(new ProcessInfo(instance.Id,
instance.ProcessName,
instance.TotalProcessorTime.TotalMilliseconds,
instance.WorkingSet64,
instance.MainModule.FileName));
}
catch { }
}
return pInfo;
}
#endregion #region 结束指定进程
/// <summary>
/// 结束指定进程
/// </summary>
/// <param name="pid">进程的 Process ID</param>
public static void EndProcess(int pid)
{
try
{
Process process = Process.GetProcessById(pid);
process.Kill();
}
catch { }
}
#endregion #region 获取 IP 地址信息
/// <summary>
/// 获取 IP 地址信息
/// </summary>
/// <returns></returns>
public static List<IpInfo> GetIpInfo()
{
//定义范型
List<IpInfo> ipinfos = new List<IpInfo>(); ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
try
{
if ((bool)mo["IPEnabled"] == true)
{
string mac = mo["MacAddress"].ToString().Replace(':', '-');
System.Array ar = (System.Array)(mo.Properties["IpAddress"].Value);
string ip = ar.GetValue().ToString();
ipinfos.Add(new IpInfo(ip, mac));
}
}
catch { }
} return ipinfos;
}
#endregion #region 根据物理地址获取 IP 地址
/// <summary>
/// 根据物理地址获取 IP 地址
/// </summary>
/// <param name="MACAddress"物理地址></param>
/// <returns>IP 地址</returns>
public static string GetIpByMac(string MACAddress)
{
List<IpInfo> ipinfos = SystemInfo.GetIpInfo();
foreach (IpInfo ipinfo in ipinfos)
{
if (string.Compare(ipinfo.MACAddress, MACAddress, true) == )
{
return ipinfo.IPAddress;
}
} return "";
}
#endregion #region 根据 IP 地址获取物理地址
/// <summary>
/// 根据 IP 地址获取物理地址
/// </summary>
/// <param name="IPAddress"IP 地址></param>
/// <returns>物理地址</returns>
public static string GetMacByIp(string IPAddress)
{
List<IpInfo> ipinfos = SystemInfo.GetIpInfo();
foreach (IpInfo ipinfo in ipinfos)
{
if (string.Compare(ipinfo.IPAddress, IPAddress, true) == )
{
return ipinfo.MACAddress;
}
}
return "";
}
#endregion #region 获取所有网络信息
/// <summary>
/// 获取所有的网络信息
/// </summary>
/// <returns>NetInfo 网络信息范型</returns>
public static List<NetInfo> GetAllNetInfo()
{
//定义范型
List<NetInfo> ninfos = new List<NetInfo>(); //定义,获取 MIB_IFTABLE 对象
MIB_IFTABLE tbl = GetAllIfTable(); //如果成功
if (tbl != null)
{
tbl.Deserialize();
for (int i = ; i < tbl.Table.Length; i++)
{
ninfos.Add(GetNetInfo(tbl.Table[i]));
}
} return ninfos;
}
#endregion #region 获取指定类型的网络信息
/// <summary>
/// 获取指定类型的网络信息
/// </summary>
/// <param name="nettype">网络类型</param>
/// <returns>NetInfo 网络信息范型</returns>
public static List<NetInfo> GetNetInfoByType(NetType nettype)
{
//定义范型
List<NetInfo> ninfos = new List<NetInfo>(); //定义,获取 MIB_IFTABLE 对象
MIB_IFTABLE tbl = GetAllIfTable(); //如果成功
if (tbl != null)
{
tbl.Deserialize();
for (int i = ; i < tbl.Table.Length; i++)
{
NetInfo ninfo = GetNetInfo(tbl.Table[i]);
if (ninfo.Type == nettype)
{
ninfos.Add(ninfo);
}
}
} return ninfos;
}
#endregion #region 获取指定物理地址的网络信息
/// <summary>
/// 获取指定物理地址的网络信息
/// </summary>
/// <param name="MACAddress">物理地址</param>
/// <returns>NetInfo 网络信息范型</returns>
public static NetInfo GetNetInfoByMac(string MACAddress)
{
//定义,获取 MIB_IFTABLE 对象
MIB_IFTABLE tbl = GetAllIfTable(); //如果成功
if (tbl != null)
{
tbl.Deserialize();
for (int i = ; i < tbl.Table.Length; i++)
{
NetInfo ninfo = GetNetInfo(tbl.Table[i]);
if (string.Compare(MACAddress, ninfo.PhysAddr, true) == )
{
return ninfo;
}
}
} return null;
}
#endregion #region 获取指定 ip 地址的网络信息
/// <summary>
/// 获取指定 ip 地址的网络信息
/// </summary>
/// <param name="IPAddress">ip 地址</param>
/// <returns>NetInfo 网络信息范型</returns>
public static NetInfo GetNetInfoByIp(string IPAddress)
{
string MACAddress = GetMacByIp(IPAddress);
if (string.IsNullOrEmpty(MACAddress))
{
return null;
}
else
{
return GetNetInfoByMac(MACAddress);
}
}
#endregion #region 查找所有应用程序标题
/// <summary>
/// 查找所有应用程序标题
/// </summary>
/// <returns>应用程序标题范型</returns>
public static List<string> FindAllApps(int Handle)
{
List<string> Apps = new List<string>(); int hwCurr;
hwCurr = GetWindow(Handle, GW_HWNDFIRST); while (hwCurr > )
{
int IsTask = (WS_VISIBLE | WS_BORDER);
int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE);
bool TaskWindow = ((lngStyle & IsTask) == IsTask);
if (TaskWindow)
{
int length = GetWindowTextLength(new IntPtr(hwCurr));
StringBuilder sb = new StringBuilder( * length + );
GetWindowText(hwCurr, sb, sb.Capacity);
string strTitle = sb.ToString();
if (!string.IsNullOrEmpty(strTitle))
{
Apps.Add(strTitle);
}
}
hwCurr = GetWindow(hwCurr, GW_HWNDNEXT);
} return Apps;
}
#endregion /// <summary>
/// Get IFTable
/// </summary>
/// <returns>MIB_IFTABLE Class</returns>
private static MIB_IFTABLE GetAllIfTable()
{
//缓冲区大小
uint dwSize = ; //获取缓冲区大小
uint ret = GetIfTable(null, ref dwSize, false);
if (ret == )
{
//此函数仅支持于 win98/nt 系统
return null;
} //定义,获取 MIB_IFTABLE 对象
MIB_IFTABLE tbl = new MIB_IFTABLE((int)dwSize);
ret = GetIfTable(tbl.ByteArray, ref dwSize, false); //如果不成功
if (ret != )
{
return null;
} return tbl;
} /// <summary>
/// Get NetInfo Class
/// </summary>
/// <param name="row">MIB_IFROW Class</param>
/// <returns>NetInfo Class</returns>
private static NetInfo GetNetInfo(MIB_IFROW row)
{
NetInfo ninfo = new NetInfo();
ninfo.Index = row.dwIndex;
ninfo.Name = Encoding.ASCII.GetString(row.bDescr, , (int)row.dwDescrLen);
ninfo.PhysAddr = GetPhysAddr(row.bPhysAddr, (int)row.dwPhysAddrLen);
ninfo.Type = (NetType)row.dwType;
ninfo.Status = (NetState)row.dwOperStatus;
ninfo.Speed = row.dwSpeed;
ninfo.InErrors = row.dwInErrors;
ninfo.InOctets = row.dwInOctets;
ninfo.InUnknownProtos = row.dwInUnknownProtos;
ninfo.OutErrors = row.dwOutErrors;
ninfo.OutOctets = row.dwOutOctets;
return ninfo;
} /// <summary>
/// 获取格式化的物理地址
/// </summary>
/// <param name="b">字节数组</param>
/// <param name="len">长度</param>
/// <returns>无聊地址</returns>
private static string GetPhysAddr(byte[] b, int len)
{
string[] pa = new string[len];
for (int i = ; i < len; i++)
{
pa[i] = ((int)b[i]).ToString("X2");
}
return string.Join("-", pa);
} }
}

DiskInfo.cs

 using System;
using System.Collections.Generic;
using System.Text; namespace Lemony.SystemInfo
{
/// <summary>
/// 硬盘信息类
/// </summary>
public class DiskInfo
{
public DiskInfo(string DiskName, long Size, long FreeSpace)
{
this.DiskName = DiskName;
this.Size = Size;
this.FreeSpace = FreeSpace;
} private String m_DiskName;
public String DiskName
{
get { return m_DiskName; }
set { m_DiskName = value; }
} private long m_Size;
public long Size
{
get { return m_Size; }
set { m_Size = value; }
} private long m_FreeSpace;
public long FreeSpace
{
get { return m_FreeSpace; }
set { m_FreeSpace = value; }
}
}
}

因为只是查询cpu,和硬盘使用情况 只涉及到这两个类

是在控制台应用程序写的

Program.cs

 //执行该主函数时 1.获取要发送的信息 2.发送邮件
//发件人 和收件人保存在配置文件中. string Dstring = ""; //获得分区信息
string useCPU = ""; //获取CPU占用率
string useRAM = "";//获取物理内存
string userRAMs = "";//可使用的物理内存
string userMYSQLs = "";//获取数据库当前的容量
string useMYSQL = "";//获取数据库的连接数
string table = ""; //1.获取要发送的信息(根据类库)
//1.1获取分区信息
SystemInfo sysinfo = new SystemInfo();
List<DiskInfo> DInfo = sysinfo.GetLogicalDrives();
foreach (DiskInfo a in DInfo)
{
Dstring += "<font style='color:red'>"+a.DiskName + "</font> 总空间为" + Math.Round(a.Size / 1024.00000 / 1024.00000 / 1024.00000, )+"G,剩余"+Math.Round(a.FreeSpace / 1024.00000 / 1024.00000 / 1024.00000, )+"G ";
} //CPU占用率
useCPU = sysinfo.CpuLoad.ToString()+"%";
//总的物理内存
useRAM = Math.Round(sysinfo.PhysicalMemory / 1024.00000 / 1024.00000 / 1024.00000, ) + "G";
//可使用的物理内存
userRAMs = Math.Round(sysinfo.MemoryAvailable / 1024.00000 / 1024.00000, ) + "M"; //数据库连接
string sql = "select round(sum(data_length/1024/1024),2) from tables where TABLE_SCHEMA='ship_detail_data'";
userMYSQLs= DBHelper.GetScalar(sql).ToString() +"MB";
string sql1 = "select variable_value from GLOBAL_STATUS where variable_name='THREADS_RUNNING'";
useMYSQL = DBHelper.GetScalar(sql1).ToString(); //total = Dstring + "CPU占用率:" + useCPU + "; 总的物理内存:" + useRAM + "; 可使用的物理内存:" + userRAMs; table = string.Format(@"<table><tr><td colspan='2' style='text-align:center'><h3>"+DateTime.Now.ToString()+" 服务器的信息</h3></td></tr><tr> <td>硬盘信息</td><td>" + Dstring + "</td></tr><tr><td>内存信息</td><td>总物理内存:" + useRAM + ";可使用物理内存:" + userRAMs + "</td></tr><tr><td>CPU信息</td><td>CPU占用率:" + useCPU + "</td></tr><tr><td>数据库连接</td><td>数据库容量:"+userMYSQLs+"; 数据库当前连接数:"+useMYSQL+"</td></tr></table>"); send sd = new send();
sd.setmail(table);
Console.WriteLine("发送成功");
Console.ReadLine();

有点乱,没去弄别的。

主函数中还涉及到了 数据库的信息,刚开始不懂,百度了好久也什么都不太懂,后来就找组织了,经组织训示 终于在mysql (公司用的)中找到了information_schema 这里面记录了整个数据库的信息,在里面找到了两个表 tables 和GLOBAL_STATUS  其他的也没多去看(最主要是不懂英语.)。可以用就行(不过感觉有点不靠谱,网上貌似有说)。

取到数据了之后就是 发邮件了

send.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace sendmail
{
class send
{
public void setmail(string content)
{
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
client.Host = "smtp.163.com";//使用163的SMTP服务器发送邮件
client.UseDefaultCredentials = true;
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
client.Credentials = new System.Net.NetworkCredential("这是用户名", "密码");
System.Net.Mail.MailMessage Message = new System.Net.Mail.MailMessage();
Message.From = new System.Net.Mail.MailAddress("发件人的邮箱地址"); Message.To.Add("*********@***.com");//将邮件发送给QQ邮箱
Message.Subject = "电脑监测";
Message.Body = content;
Message.SubjectEncoding = System.Text.Encoding.UTF8;
Message.BodyEncoding = System.Text.Encoding.UTF8;
Message.Priority = System.Net.Mail.MailPriority.High;
Message.IsBodyHtml = true; client.Send(Message);
} }
}

发邮件 在主函数中设置了表格。

到这里基本已经搞定了 其中有链接数据库的因为用到了Help类,也不难,就没贴出来了,自己加上去就行了。

好的功能已经完成了。。。。谢谢!

获取本机CPU,硬盘等使用情况的更多相关文章

  1. 用C++和shell获取本机CPU、网卡IO、内存、磁盘等的基本信息

    用C++和shell获取本机CPU.网卡.内存.磁盘等的基本信息: 由于对C++相关的函数没多少了解,但是觉得用shell反而相对简单一些: 一.shell脚本,用来辅助C++获取主机的资源使用信息 ...

  2. Golang利用第三方包获取本机cpu使用率以及内存使用情况

    第三方包下载 $ github.com/shirou/gopsutil 获取内存方面的信息 package main import ( "fmt" "github.com ...

  3. C# 获取本机CPU序列号,MAC地址,硬盘ID,本机IP地址,计算机名,物理内存,PC类型

    首先引入服务 然后 调用 本文转载自http://blog.sina.com.cn/s/blog_7eeb43210101hf7f.html public class Computer { publi ...

  4. c#中如何获取本机MAC地址、IP地址、硬盘ID、CPU序列号等系统信息

    我们在利用C#开发桌面程序(Winform)程序的时候,经常需要获取一些跟系统相关的信息,例如用户名.MAC地址.IP地址.硬盘ID.CPU序列号.系统名称.物理内存等. 首先需要引入命名空间: us ...

  5. c#中如何获取本机用户名、MAC地址、IP地址、硬盘ID、CPU序列号、系统名称、物理内存

    我们在利用C#开发桌面程序(Winform)程序的时候, 经常需要获取一些跟系统相关的信息, 以下这些代码获取能有些用处. c#中如何获取本机用户名.MAC地址.IP地址.硬盘ID.CPU序列号.系统 ...

  6. C/C++获取Linux系统CPU和内存及硬盘使用情况

    需求分析: 不使用Top  df  free 等命令,利用C/C++获取Linux系统CPU和内存及硬盘使用情况 实现: //通过获取/proc/stat (CPU)和/proc/meminfo(内存 ...

  7. php获取linux服务器CPU、内存、硬盘使用率的实现代码

    define("MONITORED_IP", "172.16.0.191"); //被监控的服务器IP地址 也就是本机地址 define("DB_SE ...

  8. 编程获取linux的CPU使用的内存使用情况

    Linux可用下top.ps命令检查当前的cpu.mem用法.下面简单的例子: 一.采用ps查看资源消耗的过程 ps -aux 当您查看进程信息,第三列是CPU入住. [root@localhost ...

  9. [No0000112]ComputerInfo,C#获取计算机信息(cpu使用率,内存占用率,硬盘,网络信息)

    github地址:https://github.com/charygao/SmsComputerMonitor 软件用于实时监控当前系统资源等情况,并调用接口,当资源被超额占用时,发送警报到个人手机: ...

随机推荐

  1. 智能的PHP缩图类

    *作者:落梦天蝎(beluckly)*完成时间:2006-12-18*类名:CreatMiniature*功能:生成多种类型的缩略图*基本参数:$srcFile,$echoType*方法用到的参数:$ ...

  2. 怪胎:Android开发ImageView图片无法显示

    今天碰到一个非常奇怪的问题: 在Android中ImageView无法显示加载的本地SDCard图片. 具体过程是:先调用本地照相机程序摄像,然后将拍摄的图片加载在ImageView中显示. publ ...

  3. 在O(1) 时间删除链表节点

    struct Node { int val; Node * next; }; void deleteNode(Node ** head, Node * target) { assert(head != ...

  4. Thread的run()与start()的区别

    Java的线程是通过java.lang.Thread类来实现的.VM启动时会有一个由主方法所定义的线程.可以通过创建Thread的实例来创建新的线程.每个线程都是通过某个特定Thread对象所对应的方 ...

  5. bzoj1756 Vijos1083 小白逛公园

    Description 小新经常陪小白去公园玩,也就是所谓的遛狗啦-在小新家附近有一条"公园路",路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了. ...

  6. Asp.Net 构架(Http Handler 介绍) - Part.2

    原文地址:http://www.cnblogs.com/JimmyZhang/archive/2007/09/15/894124.html 引言 在 Part.1 Http请求处理流程 一文中,我们了 ...

  7. MVC 校验

    校验保障了MVC 应用程序安全性. Models 文件夹包含表示应用程序模型的类 1,创建一个项目MvcValidateDemo. 2,创建一个实体类UserInfo在Models中,包含Id.Use ...

  8. PyCharm常用设置

    pycharm,优秀的python开发工具 本文介绍一点python开发工具,pycharm的使用方式. 内容仅仅为最常用的几点,想要了解更多,请自行谷歌. 1.常用工具栏 唤出常用工具栏,View ...

  9. pyqt之倒计时例子

    from PyQt4.Qt import *from PyQt4.QtCore import *from PyQt4.QtGui import *import sysdef main():    a= ...

  10. sql获取每门课程成绩最好的学生信息

    1.相关数据表 Score表 [User]表 SQL语句例如以下: --查询出各科成绩最好的学生信息 --自连接 --SELECT TOP 1 * FROM Score B WHERE B.Score ...