65.9K
CodeProject 正在变化。 阅读更多。
Home

SYSInfo:系统信息桌面工具

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (142投票s)

2010年9月8日

GPL3

19分钟阅读

viewsIcon

316611

downloadIcon

17274

在桌面上显示系统信息,如可用磁盘空间和可用内存。

引言

此工具显示有关系统资源和设置的信息。它使用 WMI 检测和 Windows API 进行查询。目前,可供显示的系统信息如下:

  • 可用物理内存
  • 可用虚拟内存
  • 可用分页区
  • 可用磁盘空间(文本或条形图)
  • IP 地址
  • 子网掩码
  • MAC 地址
  • 默认网关
  • 网络吞吐量(文本和图表)
  • 主机名
  • 用户
  • 启动日期
  • 操作系统版本
  • 服务包
  • CPU 使用率(文本和图表)
  • 前5个进程(内存使用情况)
  • 前5个进程(CPU 使用情况)
  • 磁盘使用率(文本和图表)
  • 电池状态(文本和图表)

其他功能

  • 可在桌面上自由定位
  • 不同的背景设置(透明/渐变/纹理)
  • 支持加载背景图片
  • 支持调整背景图片颜色
  • 可修改的字体设置
  • 可修改的刷新时间
  • 硬盘条形图包含一个简单的目录浏览器
  • 显示活动网络连接,并提供 tracert、whois、关闭端口等选项

背景

这个程序是基于我在这里的第一个程序:WMIInfo。我开始做这个项目至今已经快2年了。在那段时间里,我脑海中涌现出许多关于如何扩展和增强程序的想法。由于我对原始程序做了很多修改,并且使用了除 WMI 检测之外的其他方法,我决定给这个程序起一个新的、更通用的名字……我仍然要说(就像我第一次在这里说的那样),你不应该对代码抱有太高的期望——尽管我希望我的编码水平有所提高 Wink | <img src=。当然,非常欢迎任何建议、更正或改进!

使用程序

首次启动程序时,您必须设置要显示的信息。

 

 

右侧一栏显示了可用的功能。您可以通过双击将它们添加到活动功能列表中,也可以通过双击将它们从列表中移除。

 

 

您可以通过取消勾选“全局”,为每个功能分配单独的字体类型和颜色。同样,您想要分配不同字体/颜色的功能必须在活动功能列表中被选中。通过点击字体按钮旁边的箭头按钮来分配字体/颜色。

  • 顺序:功能将按照它们在列表中出现的顺序显示。您可以使用窗体底部的箭头按钮更改顺序。
  • 标题:您可以为大多数活动功能添加单独的标题。只需选择该功能,在左侧的标题字段中写入标题,然后点击旁边的箭头按钮来分配标题。
  • 文本颜色和字体类型:当勾选“全局”时,文本颜色和字体类型将应用于整个窗体。
  • 刷新率:刷新率适用于窗体和一些功能。这是一个全局设置,用于决定窗体控件的刷新频率。然而,“使用率”功能有其自己的刷新率设置。
  • 背景渐变:这适用于整个窗体背景色的渐变。您可以指定两种颜色和渐变的角度。背景本身是通过窗体的上下文菜单选择的——我稍后会提到这一点。
  • 'Aero'玻璃效果: 这适用于启用了 DWM ('Aero') 的 Vista 到 Win8 系统。如果您在“背景”设置中启用了“aero 效果”,您可以在这里更改玻璃的颜色。
    选择“透明”会将背景色设置为窗体的透明度键。在 Vista/Win7 中,它会产生通常的玻璃外观。在 Win8 中,它会产生真正的透明外观——但在彩色背景上的渲染效果比“普通”透明度要好得多。
    • 纹理:玻璃效果上覆盖一层纹理(参见“背景”选项卡)
    • 渐变:玻璃效果上覆盖一层渐变(参见上面的“背景渐变”)
    • 透明度:所选纹理/渐变的透明级别

扩展设置

 

 

扩展设置涉及使用率功能,如 CPU 使用率、网络使用率和磁盘使用率。所有这些功能都有一个小图表,显示特定时间段内的使用情况,并按给定的刷新率更新。刷新率以毫秒为单位,时间跨度以秒为单位。

 

请记住,更高的刷新率(例如一个更小的值)会消耗更多的 CPU 资源。

对于 Win7 和 Vista,文本显示 CPU 编号,后跟核心编号,以及其实际速度,后跟实际使用率。

文本总是以网络连接的名称和其实际速度设置开头。(我不太确定,但我认为无线连接的速度在一段时间不使用后会被路由器降低。)

吞吐量图表显示每秒发送和接收的字节数。该图表是自动缩放的,因为如果缩放到最大可能速度,您将看不到太多内容。接收字节的图表是浅蓝色,而发送字节的图表是青绿色。

“禁用适配器” 包含您的网络设备列表。您可以在此处禁用它们,使其不在工具窗口中显示。

作为一个附加功能,双击网络标签会打开一个显示活动网络连接的窗口。

左键点击一个远程地址会打开一个上下文菜单,提供以下选项:

  • 跟踪路由
  • 解析 IP 地址后跟踪路由——这可能会非常慢!
  • 获取 whois 信息——查询由“GeekTools Whois Proxy”处理——它会自动查询相关的顶级域名服务
  • 通过关闭远程端口或关闭连接来终止连接

左键点击 PID 或进程,您可以选择终止该进程。

这个工具仍然有一点小问题,例如当通过点击标题对列表进行排序时,所选条目返回的值仍然是原始字段的值...

  • 磁盘使用率:显示硬盘或可移动设备(如U盘)的读写使用情况。

第一行显示驱动器号及其分区。

图表的 y 轴刻度设置为约 100Mbytes/秒。

  • 硬盘条形图:硬盘条形图是可用磁盘空间文本显示的替代方案。

您可以为 0-50、50-75 和 75-100% 的阈值指定三种颜色。这可能有点令人困惑,但这些阈值指的是已用空间——而文本值指的是可用空间。

硬盘条形图的一个附加功能是一个小文件浏览器。您可以通过左键单击条形图来打开它。

它的作用类似于 Windows 文件浏览器:双击打开文件和文件夹,右击打开上下文菜单。Shift 和 Ctrl 键也受支持。

您可以使用“测试”按钮来测试您的设置。“恢复”将设置恢复到上次保存的状态。使用“应用”按钮应用设置并关闭窗体。

背景设置

我实现了一些简单的图像处理功能:您可以加载一张图片作为工具的背景,并调整其颜色。
支持大多数图像文件类型。
别忘了只使用小图片!
颜色处理是通过 colormatrix 类完成的。这里有一个很好的例子

  • Context menu:

  • “刷新”会刷新窗体控件
  • “设置”:“更改”打开设置对话框 - “删除”恢复初始设置
  • “语言”更改控件的语言(提供英语/德语)
  • “边框”为窗体添加边框——(提供细/粗/AeroSpecial)——通过点击“边框”启用/禁用
  • “背景”选项:透明 / aero / 渐变 / 纹理(蓝色 / 灰色)
  • “锁定”目前禁用窗体的移动

透明 Aero 玻璃效果 (Vista/7) 梯度 纹理和粗边框

关注点

首先,我想感谢所有分享了他们的想法和代码的程序员,是他们使我能够编写这个程序!在此提及其中一些人:

文件浏览器和 shell 上下文菜单的灵感来源

最后,我想提一下我发现的一些基本概念和有趣的想法。我不能过多地深入细节,因为这会远远超出本文的范围。

在我的第一个程序 WMIInfo 中,我只使用了一个标签来显示系统信息。但由于我想使用图形和条形图,我必须改变显示信息的概念。目前,我在窗体上有 20 个预定义的标签,它们是功能的占位符。

随着我越来越多地使用动态创建的控件,我发现这些标签可以在需要时动态创建。但我认为目前这样做工作量太大了……

启动程序时,我们从设置文件中加载已存储的设置。

VARIABLE = Properties.Settings.Default.[Name of property]

有一个用于功能的全局数组 (iFunction[]) 和一个用于标签控件的全局数组 (cLabel[])。

活动功能的值大于 -1,并提供出现的顺序。功能数组的索引指向功能本身:

目录 函数
0 可用内存
1 可用虚拟内存
2 可用分页内存
3 可用磁盘空间
4 网络(设置和使用情况)
5 主机名
6 用户名
7 启动日期
8 操作系统版本
9 服务包
10 CPU 使用率
11 前5个进程(内存使用情况)
12 前5个进程(CPU 使用情况)
13 磁盘使用率
14 电池状态

为了显示图表而不是文本标签,我使用了面板。这些面板被分配了一个文本标签和一个图表控件。面板本身替换了控件数组中的标签。我发现我可以将控件分配给一个标签,我觉得这很有趣。但缺点是 autosize 属性对这些控件不起作用。

程序的原始工作流程如下

  • 加载设置
  • 初始化标签和功能的数组
  • 初始化所选功能
  • 定期处理功能

WMI 查询

WMI 数据的处理过程如下

string query = "SELECT * FROM Win32_OperatingSystem";
ManagementObjectSearcher seeker = new ManagementObjectSearcher(query);
ManagementObjectCollection oReturnCollection = seeker.Get();
foreach (ManagementObject m in oReturnCollection)
{
    VARIABLE = m["NAMEOFPROPERTY"];
    (...)
}

对于前5个进程,我使用了 LINQ 查询

var query = (from p in System.Diagnostics.Process.GetProcesses()
             orderby p.PrivateMemorySize64 descending
             select p)
    .Skip(0)
    .Take(5)
    .ToList();
string s = "",t = "";
foreach (var item in query)
{
    s += item.ProcessName  + "\r\n";
    t += CalcSize(item.PrivateMemorySize64.ToString(), 1)  + "\r\n";
}

当我开始使用类时,我创建了对类的全局引用。同时,我发现我可以将一个类分配给一个面板控件,并在以后引用它而无需全局引用。不知道这是否是更好的方法....

我使这些类大部分是独立的……有些类引用了计时器设置——如果你替换掉这些,你应该能够独立于本项目使用它们。

本项目中的类

要获取适配器名称,您需要像这样查询 Win32_NetworkAdapterConfiguration

string[] s = new string[0];
string query = "SELECT * FROM Win32_NetworkAdapterConfiguration " + 
               "WHERE IPEnabled = TRUE";
ManagementObjectSearcher seeker = new ManagementObjectSearcher(query);
ManagementObjectCollection oReturnCollection = seeker.Get();
foreach (ManagementObject m in oReturnCollection)
{
    try
    {
        Array.Resize(ref s, i + 1);
        s[i] = Networkadapter(m);//get name of adapter from registry
        i++;
    }
    catch
    { }
}

您可以像这样从注册表中获取名称

public string Networkadapter(ManagementObject m)
{
    RegistryKey rK = Registry.LocalMachine;
    string s = "";
    s = m["SettingID"].ToString();
    RegistryKey rSub = rK.OpenSubKey("SYSTEM\\CurrentControlSet\\Control" + 
                "\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + 
                s + "\\Connection");
    s = rSub.GetValue("Name").ToString();
    return s;
}

最后,您可以在一个循环中用以下代码为每个适配器初始化标签和图表

for (int k = 0; k < monitor.Adapters.Length; k++)
{
    netLoad[k] = new NetworkWorkload(s[k], monitor.Adapters[k]);
    monitor.Adapters[k].init();
    pNet.Controls.Add(netLoad[k].Label); //add the label control to a panel
    pNet.Controls.Add(netLoad[k].NetGraphControl); //add the graph control to a panel
}

其中 netload[] 是一个 Networkload 类的数组,pNet 是一个包含标签和图表的面板控件。

如果网络配置发生变化,例如,断开/连接 WLAN 或 LAN 时,您需要重新初始化监视器。通过事件 NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(AddressChangedCallback);,您可以检测到变化。

  • CPUProcess:CPU 使用率 - 前5个进程列表
    • 使用 processlist pList = new processlist(); 初始化
    • 使用 System.Collections.IList iList = pList.top5_list; 检索列表
  • CPUWorkload:以文本和图表形式显示 CPU 使用率
    • 使用 CPUWorkload CWL = new CPUWorkload({bool bGraph}, {bool bText}); 初始化
    • 在标签控件中检索文本:CWL.Label
    • 检索图表:CWL.CPUGraphControl
  • DiskUsage:磁盘的吞吐量(文本和图表)
    • 使用 DiskUsage du = new DiskUsage("物理分区名称的一部分 - 如 C:") 初始化
    • 在标签控件中检索文本:du.Label
    • 检索图表:du.DiskGraphControl
  • NetworkAdapter/ NetworkMonitor/ NetworkWorkload:网络吞吐量(文本和图表)
    • 使用 NetworkMonitor monitor = new NetworkMonitor({来自注册表的网络适配器名称数组}); 初始化适配器

Windows API 相关

对我来说,发现使用 Windows API 的可能性非常有趣。尽管实现文件浏览器相当困难,但当它成功运行时,也带来了巨大的喜悦。Smile | <img src= " />

这里有一些不错的小帮手。

磁盘变更通知

为了接收硬件事件的通知,您可以重写窗口消息

private const UInt32 WM_DEVICECHANGE = 0x0219;
private const UInt32 DBT_DEVICEARRIVAL = 0x8000;
private const UInt32 DBT_DEVICEREMOVECOMPLETE = 0x8004;
protected override void WndProc(ref Message m)
{
    if (iFunction[13] > -1 && m.Msg == WM_DEVICECHANGE)    {
        if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL || 
            m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE)
        {
            Action action = _diskusage_init;
            this.BeginInvoke(action);
        }
    }
    base.WndProc(ref m);
}

首先,我在这里直接调用 “_diskusage_init()” 方法时遇到了一些问题。它给我一些关于 COM 对象断开连接的奇怪消息。通过谷歌搜索,我发现这是一个线程调用问题。我用这两行代码解决了这个问题

Action action = _diskusage_init;
this.BeginInvoke(action);

在用这些代码之前,我首先使用了“传统”的委托方法。但后来我想到尝试这种方式,因为我在其他地方使用过 Marcell Spies 的 “ExecuteThreadSafe” 方法。

public static class ControlExtensions
{
    public static void ExecuteThreadSafe(this Control control, Action action)
    {
        if (control.InvokeRequired)
        {
            control.BeginInvoke(action);
        }
        else
        {
            action.Invoke();
        }
    }
}

有趣的是,运行时甚至“不知道”它需要被调用,因为当我用 this.ExecuteThreadSafe(_diskusage_init); 调用它时,我遇到了同样的错误。所以我没有查询 InvokeRequired 就强制执行了它。这仍然留下了这样一个问题:既然 “Action” 也是一个委托,并且可以完成同样的事情,为什么我们还需要声明一个全局委托和一个委托方法呢?

Aero 玻璃效果(Vista 及更高版本)

从 Vista 开始,微软引入了 DesktopWindowManager (DWM),带有一些很棒的效果,比如 Aero Glass 可以模糊窗体的背景。要使其生效,系统必须启用 Aero 和透明度。首先,你需要从 dwmapi.dll 导入一些方法。

[System.Runtime.InteropServices.DllImport("dwmapi.dll", PreserveSig = false)]
public static extern bool DwmIsCompositionEnabled();
[System.Runtime.InteropServices.DllImport("dwmapi")]
private static extern int DwmEnableBlurBehindWindow(
            System.IntPtr hWnd, ref DWM_BLURBEHIND pBlurBehind);
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
static extern IntPtr CreateRectRgn(int x1, int y1, int x2, int y2);
public struct DWM_BLURBEHIND
{
    public int dwFlags;
    public bool fEnable;
    public System.IntPtr hRgnBlur;HRGN
    public bool fTransitionOnMaximized;
}

由于这个窗体不是静态的,而是根据新的磁盘驱动器或网络连接等变化动态调整其大小,所以每次窗体调整大小时都需要初始化玻璃效果的渲染——至少这是我设法让它工作的方式;可能还有更好的解决方案。

private void Form1_Resize(object sender, EventArgs e)
{
    //Check to see if composition is Enabled / enable
    // background blurring if selected
    if (System.Environment.OSVersion.Version.Major >= 6 && 
        DwmIsCompositionEnabled())
    {
        //the rectangle region of the effect
        IntPtr hr = CreateRectRgn(0, 0, this.Width, this.Height);
        DWM_BLURBEHIND dbb;
        //bool - activate / deactivate the effect
        dbb.fEnable = bAero;
        dbb.dwFlags = 1 | 2;
        dbb.hRgnBlur = hr;
        dbb.fTransitionOnMaximized = true;
        DwmEnableBlurBehindWindow(this.Handle, ref dbb);
        this.Invalidate();
        System.Runtime.InteropServices.Marshal.Release(dbb.hRgnBlur);
    }
    else
    {
        this.Invalidate();
    }
}

当启用/禁用效果时,你需要重新创建窗体以正确应用更改。

this.RecreateHandle();

Win8 中,微软改变了很多东西——我偶然发现 DwmEnableBlurBehindWindow 并没有被移除或禁用。它与 Win7 中的玻璃效果不完全相同,因为它没有阴影。

为了让它工作,我们需要另一个 API 调用

  [DllImport("dwmapi.dll")] 
   public static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, Margins pMargins);    
  
  [StructLayout(LayoutKind.Sequential)]
   public class Margins
   { public int cxLeftWidth, cxRightWidth, cyTopHeight, cyBottomHeight;}

所以我不得不稍微扩展一下 resize 事件

if ((System.Environment.OSVersion.Version.Minor >= 2)|(bFrameChecked&&!bFrameType&&bAeroFrame))
DwmExtendFrameIntoClientArea(Handle, new Margins { cxLeftWidth = -1, cxRightWidth = -1, cyTopHeight = -1, cyBottomHeight = -1 });

我又一次偶然发现,在 Win7 中将此效果应用于一个带有“粗边框”并启用 aero 的窗口时,会产生一个漂亮的玻璃状瓷砖——因此,我在边框菜单中添加了“Aero special”选项。

在玩了一会儿 aero 之后,我添加了“渐变”和“纹理”功能。

渐变功能的实现非常简单:你只需要为渐变颜色添加/调整 alpha 通道即可

if (bAero & bAeroGradient)
{ 
    c1 = Color.FromArgb((byte)(fAeroTransparency * (float)255),c1);
    c2 = Color.FromArgb((byte)(fAeroTransparency * (float)255),c2);
}  

纹理功能需要更多的工作。我找到了一个由 Jan Romell 提供的很好的方法。代码会遍历每个像素并改变 alpha 通道。这适用于所有非索引颜色的图像。

ImageBack = ChangeImageOpacity(ImageBack, fAeroTransparency);

因此,背景图片的透明度是在 'e.Graphics.DrawImage' 命令之前设置的。

透明边框

我在绘制圆角形状或边框时遇到了一些困难。我首先尝试了一些使用圆角矩形和裁剪的想法,但结果并不如预期。最后,我找到了几篇关于重写 CreateParams 和操纵窗体样式的文章,最终得到了这个相当简单的方法。

//Window with a thin caption. Does not appear in the taskbar or in the Alt-Tab palette
public const int WS_EX_TOOLWINDOW = 0x00000080;
public const int WS_THICKFRAME = 0x800000; //window with a "sizing" border
public const int WS_BORDER = 0x00040000; //window with a thin-line border

protected override CreateParams CreateParams
{
    get
    {
        new System.Security.Permissions.SecurityPermission(
            System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode).Demand();
        CreateParams cp = base.CreateParams;
        if (bFrameChecked)
        {
            cp.Style |= bFrameType ? WS_THICKFRAME : WS_BORDER;
        }
        cp.ExStyle |= WS_EX_TOOLWINDOW;
        return cp;
    }
}

通过设置 WS_EX_TOOLWINDOW,应用程序不会出现在 ALT-TAB 列表中,也不会出现在任务管理器的应用程序列表中。

这引出了我关于透明度的一般性问题:为了使窗体透明,你首先需要设置 SetStyle(ControlStyles.SupportsTransparentBackColor, true); 来启用透明度。

然后,您需要在窗体属性中为透明度选择一种特定的颜色,并将窗体的背景色设置为所选颜色。这种方法的缺点是,每当这种颜色出现在您的控件中时,它都会变得透明!

this.BackColor = System.Drawing.Color.FromArgb(2, 2, 2);
this.TransparencyKey = System.Drawing.Color.FromArgb(2, 2, 2);

另一个缺点是,如果你像我在这里一样禁用了窗体的任何边框,你将无法再移动它。Wink | <img src= " /> 解决方案是在进入窗体时使背景不透明,然后在按下鼠标按钮并移动鼠标时调用鼠标事件。

移动一个透明无边框的窗体

private Point m_offset;
private Point m_Pos;
private void EM_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        m_Pos = Control.MousePosition;
        m_Pos.Offset(m_offset.X, m_offset.Y);
        Location = m_Pos;
    }
}
private void EM_MouseDown(object sender, MouseEventArgs e)
{
    int x1,x2,y1,y2,dx,dy;
    x1 = Location.X;
    y1 = Location.Y;
    x2 = -MousePosition.X;
    y2 = -MousePosition.Y;
    dx = x1 + x2;
    dy = y1 + y2;
    m_offset = new Point(dx,dy);
}

一些无法正常工作的地方

用于显示使用情况和图表的不同类在后台任务中运行。因此,在测试或应用设置时,窗体的控件可能不会立即显示在正确的位置,因为在窗体更新时,这些类可能尚未完全初始化。它会在下一次刷新时自行纠正。尽管如此,有时你必须手动刷新作为一种变通方法。

当背景设置为透明时,在像图片那样颜色繁多的桌面上,文本渲染效果不佳。我认为这与文本标签的透明度和抗锯齿有关,因为你可以在字母周围看到窗体背景色的微小瑕疵。

编辑: 如上所述,在 Win8 中,启用“Aero 效果”并将背景色设置为透明度键,文本渲染效果非常好。

XP

我在 XP 上测试了该程序,发现一些 WMI 类不可用,比如我用来获取 CPU 详细信息的 Win32_PerfFormattedData_Counters。因此,我不得不通过查询操作系统版本并使用不同的 WMI 类来进行查询(比如用 Win32_PerfFormattedData_PerfOS_Processor 获取 CPU 使用率,用 Win32_Processor 获取 CPU 详细信息)来解决这个问题。

最后发现,查询 "Win32_Processor" 耗时相当长,并且占用大量 CPU 资源。所以,如果你使用 XP,我建议在显示 CPU 使用率时禁用 CPU 文本。有趣的是,我在一台四核机器(运行 Win7)上不得不切换到同一个类,因为它总是显示当前 CPU 速度为零,而在双核机器上则工作正常——有谁知道为什么会这样吗(可能是因为四核是 64 位处理器)?

历史

  • 2010年9月8日:SYSInfo 1.0
  • 2010年9月19日
    • sam.hill 的要求,添加了电池状态。
    • 修复了在进行设置后更改语言时,设置对话框显示错误语言的问题。
    • JF2015 的要求,添加了一个“锁定”选项。(仍在努力实现一个“真正”的锁定选项。)
    • JF2015 的请求,从 ALT-TAB 列表中移除了该应用程序。
    • 在上下文菜单 - 设置中添加了一个“删除”选项。如果设置文件损坏,您现在可以通过此选项恢复初始设置。
  • 2010年9月25日
    • 增加了一个“活动连接”窗口,包含'whois'、'tracert'和'关闭端口'等多种选项。
      通过双击网络标签打开该窗口。

      对于活动连接,我使用了来自 Warlib 的一个类,地址为 https://codeproject.org.cn/KB/IP/iphlpapi2.aspx

    • 添加了加载背景图片和颜色处理的支持

      (我在演示文件夹中添加了一些纹理用于测试。)
  • 2013年1月3日
    • 一些错误修复,例如当驱动器报告可用空间为“0”(主要是 CD)时出现的未处理异常。
    • 扩展了文件浏览器的工具提示
    • 为 Win8 添加了“aero”玻璃效果支持
    • 为“aero”玻璃背景添加了颜色选项
  • 2013年1月6日
    • 将 NeutralResourcesLanguage 更改为“english”——这样,如果 UI 回退到中性语言,您就不会被“德语”所困扰了 Wink | <img src= " src="https://codeproject.org.cn/script/Forums/Images/smiley_wink.gif" />
  • 2013年1月7日
    • 将 settings.settings 中的默认语言更改为“EN-gb”
    • 添加了一个用于隐藏/禁用硬盘的列表——当安装了读卡器时可能很有用。
  • 2013年1月13日
    • 在 win8 中玩了一会儿“aero”的东西后,我最终添加了一些选项
      • 纹理:玻璃效果上覆盖一层纹理
      • 渐变:玻璃效果上覆盖一层渐变
      • 透明度:使覆盖层透明——嗯,这是主要功能
我还没在 win7 上试过——所以我现在真的说不准它在那里的效果如何,甚至是否能用……也许明天在办公室秘书的电脑上试试 Wink | <img src= " src="https://codeproject.org.cn/script/Forums/Images/smiley_wink.gif" />
  • 2013年1月30日
    • 文件浏览器的小错误修复 - 右键单击文件时选择了错误的属性
  • 2014年2月28日
    • 小错误修复
    • 为 CPU 使用率图表和文本显示添加了“总计”选项 / 这样它只显示平均使用率,而不是所有单个核心
    • 尝试了一个针对 win8 关于记录启动时间新“行为”的变通方法
    • 将磁盘使用图的刻度从固定值更改为“自动”
  • 2014年4月18日
    • 错误修复:在某些系统上,由于 RPC 服务的计时问题,应用程序会冻结。我认为在 Windows 8.x 上情况更糟。可能他们对调用的处理方式做了一些改变……?
      因此,我为所有 wmi 查询添加了一个锁

      private ReaderWriterLockSlim dcLock = new ReaderWriterLockSlim();

      if (dcLock.TryEnterWriteLock(50))
      (...)

      我观察了几天,现在似乎可以正常工作了……
    • 为文件夹浏览器添加了 zip 文件预览 - 提取功能尚未实现。
    •  
  • 2014年10月28日
    • 小更新 - whois 服务提供商 "whois-server(s).net" 似乎不再接受查询 - 已切换到 "whois.ripe.net"
      顺便问一下,有谁知道像 ripe 这样好用又免费的 whois 服务提供商吗?Ripe 速度很快,但它不托管所有记录……
  • 2015年8月4日
    • 更改了磁盘容量条的设计


       
    • 为可用系统内存添加了一个水平条
    • 添加了真正的锁定选项
      该应用程序会在桌面图标后面的最低层生成一个新窗口。
      因此它不再可移动或可访问。
      已在 win7, 8, 10 上测试

      非常感谢 Gerald Degeneve 最终使这一切成为可能!看看他的文章:“在 Windows 8 的桌面图标后面绘图
      • 如果您激活了字体缩放(比如在小型高分辨率屏幕上),这可能会出现问题。
        您可以尝试在程序的兼容性设置中禁用 DPI 缩放 (SYSInfo.exe)
         

    • 在通知区域添加了一个图标——以便在锁定状态下访问该应用程序


       
    • 添加了“保存设置”选项
    • 一些错误修复,例如更改语言或使用文件浏览器时应用程序崩溃
    • 扩展了选择“刷新”选项时的函数调用 - 现在所有内容都应该被刷新
      当网络适配器发生变化时,刷新仍存在问题——因此这应该是一个临时的解决方法
       
  • 2015年8月7日
    • 进行了一些外观上的修复
      • 设置窗口现在将在屏幕中心附近打开(在高分辨率显示器上进行 dpi 缩放时,窗口顶部会移出屏幕)
      • 图表的新背景
      • 现在条形的缩放应该是一致的

        我仍在努力解决高分辨率显示器上的 dpi 缩放问题
        如上所述,您也应该尝试在应用程序的兼容性设置中禁用 DPI 缩放。
         
  • 2015年8月10日
    • 添加了“dpi-awareness”以修复小型高分辨率显示器上的缩放问题。(https://msdn.microsoft.com/library/windows/desktop/ff684173(v=vs.85).aspx)
      要禁用操作系统的 DPI 自动缩放,您必须添加一个带有选项 <dpiAware>true</dpiAware> 的应用程序清单文件。
      DPI 缩放的计算方式如下:96 dpi 是默认值。所以当显示器设置为 144 dpi 时,你只需用 144 除以 96,然后将结果乘以期望的尺寸。
      在我的代码中,它看起来是这样的
              private int DPIScaling(int iPixel)
              {
                  Graphics graphics;
                  graphics = Graphics.FromHwnd(this.Handle);
                  var dpiX = graphics.DpiX;
                  var dpiY = graphics.DpiY;
      
                  if (dpiX > 0)
                      return (int)((float)iPixel * (dpiX / 96.0));
                  else
                      return iPixel;
      
              }
    • 根据 Youregi 的建议,添加了一个“隐藏”选项
       
© . All rights reserved.