jjzjj

c# - 在继续之前强制挂载 USB 拇指驱动器

coder 2024-06-17 原文

我正在使用 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;
            }
        }
    }
}

希望对您有所帮助。

关于c# - 在继续之前强制挂载 USB 拇指驱动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19691803/

有关c# - 在继续之前强制挂载 USB 拇指驱动器的更多相关文章

  1. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  2. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  3. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  4. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  5. ruby - 继续,未定义 callcc 方法 - 2

    我想学习一些关于Continuation的知识,使用callcc方法从一些文章中键入几个示例,但我遇到了错误:NoMethodError:undefinedmethod`callcc'formain:Objectfrom(pry):2:in`'没有文章提到包含延续库。那么如何解决这个问题呢?谢谢编辑:ruby1.9.2p290(2011-07-09修订版32553)[x86_64-linux] 最佳答案 您需要要求“继续”。require'continuation' 关于ruby-继续,

  6. ruby-on-rails - 如何在 Ruby on Rails 中实现由 JSF 2.0 (Primefaces) 驱动的 UI 魔法 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道ruby​​onrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim

  7. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  10. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

随机推荐