在 C# 中为远程安装程序应用程序创建准确的进度条
Creating an accurate progress bar for remote installer application in C#
这里是 C# 的新手,我在学习的过程中学到了很多东西。
我正在创建一个远程安装补丁的 Winforms 应用程序。基本上,您给它一个文件(.msi 或 .exe)和一个计算机列表,它会在列表中向下移动,直到安装了所有补丁。它似乎正在为我想要它做的事情工作。只需点击一下即可进行 vuln/patch 管理。作为记录,我使用 PSexec 和 powershell 来完成相同的任务,它们非常棒。自己摆弄一下,希望能在这个过程中有所学习。
我想为应用程序创建一个准确的进度条,以便管理员可以大致了解当时正在处理哪些进程。可能需要修补的系统数量范围很广,从 10 个系统到 1000 个以上不等。
我看过进度条实现的教程,但大部分都是基于代码编写者估计特定作业的任务完成时间。由于每个补丁大小、安装时间和计算机数量都不同,这似乎对我没有太大帮助。
private void Start_Click(object sender, EventArgs e)
{
string complist = openFileDialog2.FileName;
string patch = textBox2.Text;
string fileName = patch;
string patchfile = Path.GetFileName(fileName);
foreach (string line in File.ReadLines(complist))
{
//Checks if C:\PatchUpdates exists on remote machine. If not, a folder is created.
if (!Directory.Exists(@"\" + line + @"\C$\PatchUpdates"))
{
Directory.CreateDirectory(@"\" + line + @"\C$\PatchUpdates");
}
//XCOPY patch to every computer
System.Diagnostics.Process processCopy = new System.Diagnostics.Process();
ProcessStartInfo StartInfo = new ProcessStartInfo();
StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
StartInfo.FileName = "cmd";
StartInfo.Arguments = string.Format("/c xcopy " + patch + " " + @"\{0}\C$\PatchUpdates /K /Y", line);
processCopy.StartInfo = StartInfo;
processCopy.Start();
processCopy.WaitForExit();
//Checks filename and installs according to file type.
if (patch.Contains(".msi"))
{
//Uses WMI to execute a remote command to install using msiexec.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processmsi = { @"cmd.exe /c msiexec /qn /i " + @"C:\PatchUpdates\" + patchfile + @" /norestart" };
object result = WMIprocess.InvokeMethod("Create", processmsi);
}
else if (patch.Contains(".exe"))
{
//Uses WMI to execute a remote command to install using commandline.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processexe = { @"cmd.exe /c C:\PatchUpdates\" + patchfile + @" /silent /norestart" };
object result = WMIprocess.InvokeMethod("Create", processexe);
}
else if (patch.Contains(".msu"))
{
//Uses WMI to execute a remote command to install using WUSA.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processmsu = { @"wusa " + patchfile + " /quiet /norestart" };
object result = WMIprocess.InvokeMethod("Create", processmsu);
}
}
}
上面的代码完成了大部分工作。当用户单击 "Start" 时,补丁将复制到每台计算机上的 C:\PatchUpdates 并使用 WMI 安装。
我如何制作一个进度条,该进度条基于计算完成每项任务所花费的时间,并在最后一台计算机安装补丁时以 100% 完成?
我假设需要做很多工作才能做到这一点。
感谢任何帮助。
您需要先获取行数(您的系统计数)。
如果您使用的是 .Net 4.0 或更高版本,您可以使用
var lineCount = File.ReadLines(@"C:\file.txt").Count();
否则你可以先做
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
之后,您将进度条的最小值设置为 0,将最大值设置为此系统数。在 foreach 中你只需要做一个 progressbar.PerformStep.
public void loadFiles()
{
// Sets the progress bar's minimum value to a number representing
// no operations complete -- in this case, no files read.
progressBar1.Minimum = 0;
// Sets the progress bar's maximum value to a number representing
// all operations complete -- in this case, all five files read.
progressBar1.Maximum = Convert.ToInt(lineCount); // in our case to the number of systems
// Sets the Step property to amount to increase with each iteration.
// In this case, it will increase by one with every file read.
progressBar1.Step = 1;
// Uses a for loop to iterate through the operations to be
// completed. In this case, five files are to be copied into memory,
// so the loop will execute 5 times.
for (int i = 0; i <= 4; i++)
{
// Inserts code to copy a file
progressBar1.PerformStep();
// Updates the label to show that a file was read.
label1.Text = "# of Files Read = " + progressBar1.Value.ToString();
}
}
这里是 C# 的新手,我在学习的过程中学到了很多东西。
我正在创建一个远程安装补丁的 Winforms 应用程序。基本上,您给它一个文件(.msi 或 .exe)和一个计算机列表,它会在列表中向下移动,直到安装了所有补丁。它似乎正在为我想要它做的事情工作。只需点击一下即可进行 vuln/patch 管理。作为记录,我使用 PSexec 和 powershell 来完成相同的任务,它们非常棒。自己摆弄一下,希望能在这个过程中有所学习。
我想为应用程序创建一个准确的进度条,以便管理员可以大致了解当时正在处理哪些进程。可能需要修补的系统数量范围很广,从 10 个系统到 1000 个以上不等。
我看过进度条实现的教程,但大部分都是基于代码编写者估计特定作业的任务完成时间。由于每个补丁大小、安装时间和计算机数量都不同,这似乎对我没有太大帮助。
private void Start_Click(object sender, EventArgs e)
{
string complist = openFileDialog2.FileName;
string patch = textBox2.Text;
string fileName = patch;
string patchfile = Path.GetFileName(fileName);
foreach (string line in File.ReadLines(complist))
{
//Checks if C:\PatchUpdates exists on remote machine. If not, a folder is created.
if (!Directory.Exists(@"\" + line + @"\C$\PatchUpdates"))
{
Directory.CreateDirectory(@"\" + line + @"\C$\PatchUpdates");
}
//XCOPY patch to every computer
System.Diagnostics.Process processCopy = new System.Diagnostics.Process();
ProcessStartInfo StartInfo = new ProcessStartInfo();
StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
StartInfo.FileName = "cmd";
StartInfo.Arguments = string.Format("/c xcopy " + patch + " " + @"\{0}\C$\PatchUpdates /K /Y", line);
processCopy.StartInfo = StartInfo;
processCopy.Start();
processCopy.WaitForExit();
//Checks filename and installs according to file type.
if (patch.Contains(".msi"))
{
//Uses WMI to execute a remote command to install using msiexec.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processmsi = { @"cmd.exe /c msiexec /qn /i " + @"C:\PatchUpdates\" + patchfile + @" /norestart" };
object result = WMIprocess.InvokeMethod("Create", processmsi);
}
else if (patch.Contains(".exe"))
{
//Uses WMI to execute a remote command to install using commandline.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processexe = { @"cmd.exe /c C:\PatchUpdates\" + patchfile + @" /silent /norestart" };
object result = WMIprocess.InvokeMethod("Create", processexe);
}
else if (patch.Contains(".msu"))
{
//Uses WMI to execute a remote command to install using WUSA.
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
ManagementScope WMIscope = new ManagementScope(
string.Format("\\{0}\root\cimv2", line));
WMIscope.Connect();
ManagementClass WMIprocess = new ManagementClass(
WMIscope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
object[] processmsu = { @"wusa " + patchfile + " /quiet /norestart" };
object result = WMIprocess.InvokeMethod("Create", processmsu);
}
}
}
上面的代码完成了大部分工作。当用户单击 "Start" 时,补丁将复制到每台计算机上的 C:\PatchUpdates 并使用 WMI 安装。
我如何制作一个进度条,该进度条基于计算完成每项任务所花费的时间,并在最后一台计算机安装补丁时以 100% 完成? 我假设需要做很多工作才能做到这一点。
感谢任何帮助。
您需要先获取行数(您的系统计数)。
如果您使用的是 .Net 4.0 或更高版本,您可以使用
var lineCount = File.ReadLines(@"C:\file.txt").Count();
否则你可以先做
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
之后,您将进度条的最小值设置为 0,将最大值设置为此系统数。在 foreach 中你只需要做一个 progressbar.PerformStep.
public void loadFiles()
{
// Sets the progress bar's minimum value to a number representing
// no operations complete -- in this case, no files read.
progressBar1.Minimum = 0;
// Sets the progress bar's maximum value to a number representing
// all operations complete -- in this case, all five files read.
progressBar1.Maximum = Convert.ToInt(lineCount); // in our case to the number of systems
// Sets the Step property to amount to increase with each iteration.
// In this case, it will increase by one with every file read.
progressBar1.Step = 1;
// Uses a for loop to iterate through the operations to be
// completed. In this case, five files are to be copied into memory,
// so the loop will execute 5 times.
for (int i = 0; i <= 4; i++)
{
// Inserts code to copy a file
progressBar1.PerformStep();
// Updates the label to show that a file was read.
label1.Text = "# of Files Read = " + progressBar1.Value.ToString();
}
}