我有一个故障的USB记忆棒,一直保持连接和断开状态,间隔时间大约为500毫秒,以保存文件,我写了一个逐字节复制文件的软件,每当USB记忆棒断开连接,软件等待然后一次又一次地尝试。
它有效,但Windows不时会向我显示一个消息框,询问它无法到达驱动器以及它应该做什么,我想知道我是否能够以某种方式阻止此消息显示,以便我的应用程序无论如何都会继续工作?
您可以从存储库下载代码: https://github.com/movsar/copynomatterwhat
以下是源代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Diagnostics;
namespace CopyNoMatterWhat
{
public class Program
{
private static DriveInfo di;
private static int DELAY = 250;
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs;
TryAgain:
try {
dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName)) {
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files) {
string temppath = Path.Combine(destDirName, file.Name);
if (!(new FileInfo(temppath).Exists)) copy(file.FullName, temppath, file.Length);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs) {
foreach (DirectoryInfo subdir in dirs) {
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
} catch (Exception ex) {
Thread.Sleep(DELAY);
Debug.WriteLine("Get Files Fail");
goto TryAgain;
}
Debug.WriteLine("Done");
}
static void Main(string[] args)
{
di = new DriveInfo("f:");
DirectoryCopy(@"F:\", "out", true);
}
private static void copy(string path, string name, long fileLength)
{
byte[] data = null;
byte[] chunk = null;
int bufferSize = 1024;
Console.WriteLine("Copying " + path);
FileStream fin;
long index = 0;
TryAgain1: try {
fin = new FileStream(path, FileMode.Open);
using (BinaryReader binReader = new BinaryReader(fin, new ASCIIEncoding())) {
while (data == null || (data.Length < fileLength)) {
binReader.BaseStream.Position = index;
chunk = binReader.ReadBytes(bufferSize);
if (data == null) data = chunk; else data = CombineByteArrays(data, chunk);
index = binReader.BaseStream.Position;
Console.Write("\r{0} / {1}", data.Length, fileLength);
}
}
} catch (IOException ex) {
Debug.WriteLine("TA 1: " + ex.Message);
Thread.Sleep(DELAY);
goto TryAgain1;
}
File.WriteAllBytes(name, data);
fin.Close();
Console.Write(" ... OK");
Console.WriteLine();
}
public static byte[] CombineByteArrays(byte[] first, byte[] second)
{
byte[] ret = new byte[first.Length + second.Length];
Buffer.BlockCopy(first, 0, ret, 0, first.Length);
Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);
return ret;
}
}
}
答案 0 :(得分:1)
在不知道对话框的样子的情况下,很难准确猜出发生了什么。我的建议是禁用关键错误对话框:
[DllImport("kernel32.dll")]
static extern ErrorModes SetErrorMode(ErrorModes uMode);
[Flags]
public enum ErrorModes : uint {
SEM_FAILCRITICALERRORS = 0x0001,
SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
SEM_NOGPFAULTERRORBOX = 0x0002,
SEM_NOOPENFILEERRORBOX = 0x8000
}
...
var em = ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOOPENFILEERRORBOX;
SetErrorMode(SetErrorMode(em) | em);
(调用两次是important)