我正在Windows 7上使用Visual Studio 2008在C#上编写更新程序。我希望用户插入USB拇指驱动器,如果程序找到了该驱动器并在驱动器上进行更新,则它将自动将其复制过来。我希望在启动时只检查一次,然后执行一个不知道更新的程序(确实需要在程序关闭时进行更新)。
我的问题是,在安装拇指驱动器之前,正在运行更新程序,因此计算机没有检测到拇指驱动器,也没有更新,并且过早地运行。我希望一切都尽可能快地运行,但是我需要在检测到之前安装所有拇指驱动器。一切都必须是自动的,用户无须输入。
在C#中这可能吗?
详细编辑:
我目前在启动时运行一个批处理文件(实际上是Windows 7 shell,但是我不确定这会有所作为)。批处理文件先运行更新检查,然后运行实际程序。如果用户在启动时将USB驱动器卡住,那么我希望更新程序查看该驱动器并复制任何新文件。
当前编码如下:
DriveInfo[] ListDrives = DriveInfo.GetDrives();
foreach (DriveInfo Drive in ListDrives)
{
if(Drive.DriveType == DriveType.Removable)
{
// double check it's valid and copy over stuff
}
}
但它目前在启动时找不到驱动器。如果我稍后运行它,那么一切都很好。我假设自从我这么早运行更新程序以来,就没有机会安装它,但是我不必等待N秒,因为在通常情况下,这只是死时间。
如果我可以执行此检查,那么与必须连续监视事件然后关闭所有内容并进行更新相比,要容易得多。
我建议一种类似以下的解决方案:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
/// <summary>
/// Represents our program class which contains the entry point of our application.
/// </summary>
public class Program
{
/// <summary>
/// Represents the entry point of our application.
/// </summary>
/// <param name="args">Possibly spcified command line arguments.</param>
public static void Main(string[] args)
{
RemovableDriveWatcher rdw = new RemovableDriveWatcher(); // Create a new instance of the RemoveableDriveWatcher class.
rdw.NewDriveFound += NewDriveFound; // Connect to the "NewDriveFound" event.
rdw.DriveRemoved += DriveRemoved; // Connect to the "DriveRemoved" event.
rdw.Start(); // Start watching.
// Do something here...
Console.ReadLine();
rdw.Stop(); // Stop watching.
}
/// <summary>
/// Is executed when a new drive has been found.
/// </summary>
/// <param name="sender">The sender of this event.</param>
/// <param name="e">The event arguments containing the changed drive.</param>
private static void NewDriveFound(object sender, RemovableDriveWatcherEventArgs e)
{
Console.WriteLine(string.Format("Found a new drive, the name is: {0}", e.ChangedDrive.Name));
}
/// <summary>
/// Is executed when a drive has been removed.
/// </summary>
/// <param name="sender">The sender of this event.</param>
/// <param name="e">The event arguments containing the changed drive.</param>
private static void DriveRemoved(object sender, RemovableDriveWatcherEventArgs e)
{
Console.WriteLine(string.Format("The drive with the name {0} has been removed.", e.ChangedDrive.Name));
}
}
RemoveableDriveWatcher类如下所示:
/// <summary>
/// Repesents a watcher class for removable drives.
/// </summary>
public class RemovableDriveWatcher
{
/// <summary>
/// Represents the watcher thread which watches for new drives.
/// </summary>
private Thread watcherThread;
/// <summary>
/// Continas all found logical drives of this system.
/// </summary>
private List<DriveInfo> foundDrives;
/// <summary>
/// Initializes a new instance of the <see cref="RemovableDriveWatcher"/> class.
/// </summary>
public RemovableDriveWatcher()
{
this.foundDrives = new List<DriveInfo>();
this.watcherThread = new Thread(new ThreadStart(ScanLogicalDrives));
this.WaitBetweenScansDelay = 1000;
}
/// <summary>
/// Is fired if a new drive has been detected.
/// </summary>
public event EventHandler<RemovableDriveWatcherEventArgs> NewDriveFound;
/// <summary>
/// Is fired if a drive has been removed.
/// </summary>
public event EventHandler<RemovableDriveWatcherEventArgs> DriveRemoved;
/// <summary>
/// Gets or sets the delay in ms between two scans.
/// </summary>
public int WaitBetweenScansDelay
{
get;
set;
}
/// <summary>
/// Starts the watcher.
/// </summary>
public void Start()
{
if (!this.watcherThread.IsAlive)
{
this.watcherThread.Start();
}
}
/// <summary>
/// Stops the watcher.
/// </summary>
public void Stop()
{
if (this.watcherThread.IsAlive)
{
this.watcherThread.Abort();
this.watcherThread.Join();
}
}
/// <summary>
/// Scans for logical drives and fires an event every time a new
/// drive has been found or a drive was removed.
/// </summary>
private void ScanLogicalDrives()
{
DriveInfo[] drives;
do
{
drives = DriveInfo.GetDrives();
// Check for new drives
foreach (DriveInfo drive in drives)
{
if (!(drive.DriveType == DriveType.Removable))
{
continue;
}
if (!drive.IsReady)
{
continue;
}
if (!this.foundDrives.ContainsWithName(drive))
{
this.foundDrives.Add(drive);
if (this.NewDriveFound != null)
{
this.NewDriveFound(this, new RemovableDriveWatcherEventArgs(drives, drive));
}
}
}
// Check for removed drives
for (int i = this.foundDrives.Count - 1; i >= 0; i--)
{
DriveInfo drive = this.foundDrives[i];
if (!drives.ContainsWithName(drive))
{
if (this.DriveRemoved != null)
{
this.DriveRemoved(this, new RemovableDriveWatcherEventArgs(drives, drive));
}
this.foundDrives.RemoveWithName(drive);
}
}
// Sleep
Thread.Sleep(this.WaitBetweenScansDelay);
}
while (true);
}
}
为了使一切正常工作,您需要RemovableDriveWatcherEventArgs:
/// <summary>
/// Represents the RemovableDriveWatcherEventArgs
/// </summary>
public class RemovableDriveWatcherEventArgs : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="RemovableDriveWatcherEventArgs"/> class.
/// </summary>
/// <param name="allDrives">All currently available logical drives in the system.</param>
/// <param name="changedDrive">The changed drive.</param>
public RemovableDriveWatcherEventArgs(DriveInfo[] allDrives, DriveInfo changedDrive)
{
this.Drives = allDrives;
this.ChangedDrive = changedDrive;
}
/// <summary>
/// Gets the changed logical drive that has either been detected or removed.
/// </summary>
public DriveInfo ChangedDrive { get; private set; }
/// <summary>
/// Gets all currently available logical drives.
/// </summary>
public DriveInfo[] Drives { get; private set; }
}
当然还有扩展:
/// <summary>
/// Contains extensions used by the RemovableDriveWatcher class.
/// </summary>
public static class RemovableDriveWatcherExtensions
{
/// <summary>
/// Extends the DiveInfo[] by the ContainsWithName method.
/// </summary>
/// <param name="all">The array where we want to find the specified instance.</param>
/// <param name="search">The instance which we want to find in the array.</param>
/// <returns>TRUE if the specified instance was found, FALSE if the specified instance was not found.</returns>
public static bool ContainsWithName(this DriveInfo[] all, DriveInfo search)
{
for (int i = 0; i < all.Length; i++)
{
if (all[i].Name == search.Name)
{
return true;
}
}
return false;
}
/// <summary>
/// Extends the List<DriveInfo> by the ContainsWithName method.
/// </summary>
/// <param name="all">The array where we want to find the specified instance.</param>
/// <param name="search">The instance which we want to find in the list.</param>
/// <returns>TRUE if the specified instance was found, FALSE if the specified instance was not found.</returns>
public static bool ContainsWithName(this List<DriveInfo> all, DriveInfo search)
{
for (int i = 0; i < all.Count; i++)
{
if (all[i].Name == search.Name)
{
return true;
}
}
return false;
}
/// <summary>
/// Extends the List<DriveInfo> by the RemoveWithName method.
/// </summary>
/// <param name="all">The array where we want to removed the specified instance.</param>
/// <param name="search">The instance which we want to remove in the list.</param>
public static void RemoveWithName(this List<DriveInfo> all, DriveInfo search)
{
for (int i = 0; i < all.Count; i++)
{
if (all[i].Name == search.Name)
{
all.RemoveAt(i);
return;
}
}
}
}
我希望这会有所帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句