这个备份器放在项目目录下面,每次使用就双击一下,因为便捷性,就不采用xml等等储存信息,全部在面板内做,这样可以保证一个exe就运行了.
我发现运行起来还蛮快的,唯一没有实现的是ping通的电脑如果出现空密码登陆,没有登陆过,还是会有问题…要保证先连接过那台电脑
如果可以写个大的,例如直接把局域网给弄通了就好了0.0
代码仅供参照..
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using static JingJingBoxDD.Intranet;
namespace JingJingBoxDD
{
public partial class IntranetBackupDevice : Form
{
#if 宏
private const string _pcNameMostly = "A2";
private const string _proName = "01.饰施图";
#elif 锐
private const string _pcNameMostly = "hzr";
private const string _proName = "01.施工图";
#endif
private string currentPath;
private bool on_off = false;//暂停修改checkedListBox1
/// <summary>
/// 点击计数,用于重新初始化
/// </summary>
private static int CheckedListBox1Counter = 0;
//关闭
private void Button2_Click(object sender, EventArgs e)
{
Close();
}
//作者信息
private void Button3_Click(object sender, EventArgs e)
{
string jj = "www.cnblogs.com/JJBox";
DialogResult dr = MessageBox.Show(
"说明:本程序会在'备份器exe所在位置'进行备份" +
"\n此文件夹前将视为'项目文件夹': " + _proName +
"\n更换网段时候后需要重新ping" +
"\n\n作者:刘启宏 企鹅:540762622" +
"\n博客: " + jj + " ('确定' 进入博客)"
, "惊惊盒子",
MessageBoxButtons.OKCancel
);
if (dr == DialogResult.OK)
{
System.Diagnostics.Process.Start(jj);
}
}
public IntranetBackupDevice()
{
try
{
InitializeComponent();
TopMost = true;//置顶窗体
FormBorderStyle = FormBorderStyle.FixedDialog;//设置边框为不可调节
StartPosition = FormStartPosition.CenterScreen;//在当前屏幕中央
checkedListBox1.HorizontalScrollbar = true;//显示垂直滚动条
checkedListBox1.ScrollAlwaysVisible = true;//显示水平滚动条
checkedListBox1.CheckOnClick = true;//按一下就打钩
textBox3.Text = NetworkSegment;
label6.Text = "默认主机:" + _pcNameMostly;
button1.TabIndex = 0;
//获取exe完整路径,若是网络驱动器,就转换,本地就原本
currentPath = PathTool.GetUNCPath(Process.GetCurrentProcess().MainModule.FileName);
//可以获得不带文件名的路径
currentPath = Path.GetDirectoryName(currentPath);
string fileName = StringTool.PathToFileNameProjectName(currentPath, 1);//获取文件名
if (_proName == fileName)//获取项目名
{
textBox2.Text = StringTool.PathToFileNameProjectName(currentPath, 2);
label7.Text = "警告:无";
}
else
{
label7.Text = string.Format("警告:当前备份器exe不在 {0} 内,将采用以上对话框信息备份.", _proName);
textBox2.Text = fileName;
}
var beifennian = StringTool.GetFlie4Number(textBox2.Text);
if (beifennian == "0")//年份确定
{
DateTime currentTime = DateTime.Now;
textBox4.Text = currentTime.Year.ToString();
}
else
{
textBox4.Text = beifennian;
}
{
//执行死循环修改的
//创建线程 Invoke方法是同步的方法,所以执行过程是有先后顺序的,所以就不会出现那个异常了
Thread newThread = new Thread(new ThreadStart(Runtime))
{
//加上这句话,否则在关闭窗体时会出现如下错误:在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。
IsBackground = true
};
newThread.Start();
}
{
ThreadPool.GetMaxThreads(out int max, out int maxIo);
ThreadPool.GetMinThreads(out int min, out int minIo);
int ipNumbers = ipNumber + 1;
if (max - ipNumbers > 0)
{
max = ipNumbers;
}
if (maxIo - ipNumbers > 0)
{
maxIo = ipNumbers;
}
if (min - ipNumbers < 0)
{
min = ipNumbers;
}
if (minIo - ipNumbers < 0)
{
minIo = ipNumbers;
}
//启动线程池
bool maxbool = ThreadPool.SetMaxThreads(max, maxIo);
bool minbool = ThreadPool.SetMinThreads(min, minIo);
if (maxbool && minbool)
{
Button4_Click(null,null);//开始就执行遍历局域网
label7.Text = string.Format("注明:线程数设置{0},{1},{2},{3}", max, maxIo, min, minIo);
}
else
{
label7.Text = "警告:线程数设置失败";
}
}
}
catch (Exception e)
{
label7.Text = e.Message;
throw e;
}
}
/// <summary>
/// 点击备份
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button1_Click(object sender, EventArgs e)
{
string dPath = textBox1.Text;
if (dPath != "")
{
if (Directory.Exists(dPath))//防止第二次点击备份
{
label7.ForeColor = System.Drawing.Color.Blue;
label7.Text = "警告:路径已经存在,请更换路径!(是否重复备份了?)";
}
else
{
bool flag = FileTool.Copy(currentPath, dPath);//复制文件
if (flag)
{
label7.ForeColor = System.Drawing.Color.MediumSeaGreen;
label7.Text = "备份成功!";
button5.TabIndex = 0;//设置焦点到打开文件夹
}
else
{
label7.ForeColor = System.Drawing.Color.Blue;
label7.Text = "警告:备份不成功,已执行回滚,请再尝试!";
}
}
}
else
{
label7.ForeColor = System.Drawing.Color.Red;
label7.Text = "警告:备份路径为空!";
}
}
/// <summary>
/// Esc键退出
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == 27) //Esc键
{
Close();
}
}
/// <summary>
/// 窗体将比其内的控件优先获得键盘事件的激活权
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
KeyPreview = true;
}
/// <summary>
/// 开始ping 遍历局域网
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button4_Click(object sender, EventArgs e)
{
//如果用多线程调用的话,会出现多个pingEnt和qiyongEnt值,对加入表造成错误例如多个A2
try
{
//暂停加表,清空表,初始化
on_off = false;
{
pingEnt++;
qiyongEnt++;
NetworkSegment = textBox3.Text;
CheckedListBox1Counter = 0;
for (int i = 0; i < checkedListBox1.Items.Count; i++)
{
checkedListBox1.Items.Clear();
}
Initialization();
}
on_off = true; //继续加入表中
for (int i = 0; i < ipNumber; i++)//生成255个线程
{
ThreadPool.QueueUserWorkItem(new WaitCallback(PingIP), new int[] { i, qiyongEnt });
}
}
catch
{
label7.Text = "警告:RunPing出错";
}
}
/// <summary>
/// 默认选中主机的时候不触发 CheckedListBox1选择事件
/// </summary>
private bool buchufagenggai = true;
/// <summary>
/// 通过委托实现死循环修改面板
/// </summary>
/// https://blog.csdn.net/htiannuo/article/details/52229695
public void Runtime()
{
HostInformation[] conames = new HostInformation[] { };
StringBuilder kongge;
while (true)
{
if (on_off)
{
lock (ComputerNames)
{
conames = ComputerNames.ToArray();
}
if (CheckedListBox1Counter < conames.Length)
{
var conameN = conames[CheckedListBox1Counter];
if (conameN.HostName != "" && conameN.HostIP != "")//锁了就应该不会出现这样的问题了
{
Invoke((EventHandler)delegate
{
//ip可能为名称,ip长度 255.255.255.255 15长+5个空格=20
int bukongge = 20 - conameN.HostName.Length;
kongge = new StringBuilder();
for (int i = 0; i < bukongge; i++)
{
kongge.Append(" ");
}
checkedListBox1.Items.Add(conameN.HostName + kongge + conameN.HostIP + " \t" + conameN.Remarks);
if (conameN.HostName == _pcNameMostly)
{
buchufagenggai = false;
//选择默认主机
checkedListBox1.SetItemCheckState(CheckedListBox1Counter, CheckState.Checked);//打钩
checkedListBox1.SelectedIndex = CheckedListBox1Counter;//焦点项
buchufagenggai = true;
}
});
}
CheckedListBox1Counter++;
//这个不能放在Invoke里面,不然又Form1窗体假死情况
Thread.Sleep(400);
}
}
}
}
/// <summary>
/// 打开文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button5_Click(object sender, EventArgs e)
{
if (Directory.Exists(textBox1.Text)) //若路径存在
{
Process.Start("explorer.exe", textBox1.Text);
}
else
{
label7.ForeColor = System.Drawing.Color.Red;
label7.Text = "警告:备份路径为空!请点击备份再点我~";
}
}
/// <summary>
/// 弄成单选
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.CurrentValue == CheckState.Checked)
{
return;//取消选中就不用进行以下操作
}
for (int i = 0; i < ((CheckedListBox)sender).Items.Count; i++)
{
((CheckedListBox)sender).SetItemChecked(i, false);//将所有选项设为不选中
}
e.NewValue = CheckState.Checked;//刷新
}
private static string patha = "";
private static string pathTime = "";
/// <summary>
/// CheckedListBox1选择事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// if (buchufagenggai)用了的话会无法直接出现在 textBox1.Text
{
//获取唯一选中项,修改textBox1路径
for (int j = 0; j < checkedListBox1.Items.Count; j++)
{
if (checkedListBox1.GetItemChecked(j))
{
try
{
var conames = ComputerNames.ToArray();
string time = StringTool.GetTimeNoSeconds(out int miao);
string pathb = @"\\" + conames[j].HostName + _SharedFolders;
string pathc = @"\\" + conames[j].HostIP + _SharedFolders;
for (int i = 0; true; i++)
{
bool pb = Directory.Exists(pathb);
if (!pb)
{
pb = Directory.Exists(pathc);
patha = pathc;
}
else
{
patha = pathb;
}
if (pb) //存在一级
{
pathTime = StringTool.GetTimeName(time, ref miao, i);//循环名称不加长
string path = ChangPath(textBox4.Text, textBox2.Text);
if (!Directory.Exists(path)) //存在就循环
{
textBox1.Text = path;
break;
}
}
else
{
DialogResult dr = MessageBox.Show(
patha + "\n\n无法连接,没有开机?不存在机名?没有访问权限?", "惊惊盒子", MessageBoxButtons.OK);
break;
}
}
}
catch
{ }
break;
}
}
}
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
if (patha != "")//防止初始化的时候就更改
{
textBox1.Text = ChangPath(textBox4.Text, textBox2.Text);
}
}
/// <summary>
/// 备份全路径
/// </summary>
/// <param name="beifennian"></param>
/// <param name="project"></param>
/// <returns></returns>
private string ChangPath(string beifennian, string project)
{
return patha + @"\" + beifennian + @"\" + project + @"\" + _proName + @"\" + pathTime;
}
private void Form1_Load(object sender, PreviewKeyDownEventArgs e)
{
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
namespace JingJingBoxDD
{
public partial class Intranet
{
public const string _SharedFoldersA = "中转站";
public const string _SharedFolders = @"\" + _SharedFoldersA;
/// <summary>
/// 网段
/// </summary>
public static string NetworkSegment { get; set; } = "192.168.1";
/// <summary>
/// 按了第几次ping,直到关闭才重置
/// </summary>
public static int pingEnt = 0;
/// <summary>
/// 启用ping的时候计数,直到关闭才重置
/// </summary>
public static int qiyongEnt = 0;
public static bool WaitOne = true;
public static int ipNumber = 256;//ip数
public static List<HostInformation> ComputerNames { get; set; } = new List<HostInformation>();//记录电脑名称和对应的ip,必须初始化,不然无法lock
public static AutoResetEvent pingOver;//线程池结束标记
/// <summary>
/// 初始化
/// </summary>
public static void Initialization()
{
WaitOne = true;
ipNumber = 256;//ip数
pingOver = new AutoResetEvent(false);//线程池结束标记
ComputerNames = new List<HostInformation>();
}
public static void PingIP(object obj)
{
var ints = obj as int[];//0是ip,1是启动点击的位置
string ip = NetworkSegment + "." + ints[0].ToString();
try
{
Ping myPing = new Ping();
PingReply reply = myPing.Send(ip, 1);
if (reply.Status.Equals(IPStatus.Success))//ping通了
{
string hostname = "";
//通过ip获取电脑名称,没有电脑名称会引起错误,造成下面无法递减,必须容错
hostname = Dns.GetHostEntry(ip).HostName;
//当前计数和启用计数要一样才加入,启用是传值的,也是固定的,
//而pingEnt是按了按钮就会改的,存在时间差,造成可以判断.
if (pingEnt == ints[1])
{
if (hostname != null && hostname.Trim() != "")
{
string[] strs = GetNetShareList(hostname);
if (strs.Length == 0)
{
//名称和ip在win10通过空密码时候验证不一样..所以两个都测试一下(如果空密码没有进入过,都会失败
strs = GetNetShareList(ip);
}
if (strs.Length > 0)
{
lock (ComputerNames)
{
if (strs.Contains(_SharedFoldersA))
{
ComputerNames.Add(new HostInformation(hostname.ToUpper(), ip, "有:" + _SharedFoldersA));
}
else
{
ComputerNames.Add(new HostInformation(hostname.ToUpper(), ip, "有共享文件夹,无:" + _SharedFoldersA));
}
}
}
}
else
{
lock (ComputerNames)
{
ComputerNames.Add(new HostInformation(ip, ip, "没有机名但是ping通了"));
}
}
}
}
}
catch
{ }
//上面必须容错,实行这里的递减
//线程池计数,用来实现最后一个线程时候通知.
ipNumber--;
//Thread.Sleep(500);
if (ipNumber == 0)
{
pingOver.Set();
}
}
public struct HostInformation
{
public string HostName;
public string HostIP;
public string Remarks;
public HostInformation(string hostname, string hostip, string remarks)
{
HostName = hostname;
HostIP = hostip;
Remarks = remarks;
}
}
/// <summary>
/// 一直等待到找到或者结束
/// </summary>
/// <param name="pcname"></param>
/// <returns></returns>
public static string WhilePing(string pcname)
{
pcname = pcname.ToUpper();
string ip = null;
try
{
while (true)
{
foreach (var item in ComputerNames.ToArray())//防止线程更改了list,必须toarray
{
if (item.HostName == pcname)
{
ip = item.HostIP; //如果找到了ip,就拿出来
break;
}
}
if (WaitOne) //等待过一次就不能再用这个函数
{
WaitOne = false;
pingOver.WaitOne();//等待 pingOver.Set();执行,表示线程池已经终止,如果线程结束,重复等待就会死掉了
}
else
{
break;
}
}
}
catch
{ }
return ip;
}
}
}
using System;
using System.Collections;
using System.Runtime.InteropServices;
namespace JingJingBoxDD
{
// https://q.cnblogs.com/q/46971/
public partial class Intranet
{
[StructLayout(LayoutKind.Sequential)]
protected struct SHARE_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_netname;
[MarshalAs(UnmanagedType.U4)]
public uint shi1_type;
[MarshalAs(UnmanagedType.LPWStr)]
public string shi1_remark;
}
[DllImport("Netapi32.dll", CharSet= CharSet.Auto)]// EntryPoint = "NetShareEnum"
protected static extern int NetShareEnum(
[MarshalAs(UnmanagedType.LPWStr)] string servername,
[MarshalAs(UnmanagedType.U4)] uint level,
out IntPtr bufptr,
[MarshalAs(UnmanagedType.U4)] int prefmaxlen,
[MarshalAs(UnmanagedType.U4)] out uint entriesread,
[MarshalAs(UnmanagedType.U4)] out uint totalentries,
[MarshalAs(UnmanagedType.U4)] out uint resume_handle
);
/// <summary>
/// 遍历某台电脑的共享文件
/// </summary>
/// <param name="server"></param>
/// <returns></returns>
public static string[] GetNetShareList(string server)
{
//-1应该是获取所有的share,msdn里面的例子是这么写的,返回0表示成功
if (NetShareEnum(server, 1, out IntPtr buffer, -1, out uint entriesread, out uint totalentries, out uint resume_handle) == 0)
{
int ptr = buffer.ToInt32();
ArrayList alShare = new ArrayList();
for (int i = 0; i < entriesread; i++)
{
SHARE_INFO_1 shareInfo = (SHARE_INFO_1)Marshal.PtrToStructure(new IntPtr(ptr), typeof(SHARE_INFO_1));
if (shareInfo.shi1_type == 0)//Disk drive类型
{
alShare.Add(shareInfo.shi1_netname);
}
ptr += Marshal.SizeOf(shareInfo);//有点类似C代码
}
string[] share = new string[alShare.Count];
for (int i = 0; i < alShare.Count; i++)
{
share[i] = alShare[i].ToString();
}
return share;
}
else
{
return null;
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace JingJingBoxDD
{
public static partial class FileTool
{
/// <summary>
/// 复制文件到文件,文件到路径,路径到路径
/// </summary>
/// <param name="sPath"></param>
/// <param name="dPath"></param>
/// <returns></returns>
public static bool Copy(string sPath, string dPath)
{
bool fa =false;
if (sPath.Length - 1 > 0 && sPath.Length - 1 > 0)
{
sPath = sPath.Trim();
while (sPath[sPath.Length - 1] == '\\')
{
sPath = sPath.Substring(0, sPath.Length - 1);
}
dPath = dPath.Trim();
while (dPath[dPath.Length - 1] == '\\')
{
dPath = dPath.Substring(0, dPath.Length - 1);
}
if (File.Exists(sPath) && File.Exists(dPath)) //都是文件
{
fa = CopyFile(sPath, dPath);
}
else if (File.Exists(sPath)) //文件复制到路径
{
fa = CopyFileToPath(sPath, dPath, true);
}
else if (Directory.Exists(sPath)) //目标路径要新建,不能判断
{
fa = CopyDirectory(sPath, dPath);
}
else
{
fa = false;
}
}
return fa;
}
/// <summary>
/// 递归拷贝所有子路径
/// </summary>
/// <param name="sPath">来源</param>
/// <param name="dPath">目标</param>
/// <returns>true成功false不成功</returns>
private static bool CopyDirectory(string sPath, string dPath)
{
bool flag = false;
if (NewFolder(dPath))
{
DirectoryInfo dir = new DirectoryInfo(sPath);//当前路径
flag = CopyFile(dir, dPath);//复制当前路径到目标路径
if (flag)
{
try
{
foreach (var 来源子路径文件夹名 in dir.GetDirectories())//获取所有子路径
{
string 来源子路径的完整路径 = 来源子路径文件夹名.FullName;
string 目标子路径的完整路径 = 来源子路径的完整路径.Replace(sPath, dPath);
if (NewFolder(目标子路径的完整路径))
{
CopyFile(来源子路径文件夹名, 目标子路径的完整路径);
CopyDirectory(来源子路径的完整路径, 目标子路径的完整路径);
}
}
}
catch
{
flag = false;
DelPath(dPath);
}
}
else
{
DelPath(dPath);
}
}
return flag;
}
/// <summary>
/// 拷贝路径下的所有文件到目标路径
/// </summary>
/// <param name="sPath">来源路径</param>
/// <param name="dPath">目标路径</param>
private static bool CopyFile(DirectoryInfo sPath, string dPath)
{
bool flag = true;
try
{
string sourcePath = sPath.FullName;//来源的全路径
FileInfo[] files = sPath.GetFiles();//获取所有文件
foreach (FileInfo file in files)//遍历所有文件
{
file.Attributes = FileAttributes.Normal; //设置为普通文件
string sourceFileFullName = file.FullName;//文件的全路径
string destFileFullName = sourceFileFullName.Replace(sourcePath, dPath);
file.CopyTo(destFileFullName, true);
}
}
catch
{
return false;
}
return flag;
}
/// <summary>
/// 复制大文件
/// </summary>
/// <param name="fromPath">源文件的路径</param>
/// <param name="toPath">文件保存的路径</param>
/// <param name="eachReadLength">每次读取的长度</param>
/// <returns>是否复制成功</returns>
private static bool CopyFile(string fromPath, string toPath)
{
int eachReadLength = 1024 * 1024 * 5;
//将源文件 读取成文件流
FileStream fromFile = new FileStream(fromPath, FileMode.Open, FileAccess.Read);//这样无法读取局域网
//已追加的方式 写入文件流
FileStream toFile = new FileStream(toPath, FileMode.Append, FileAccess.Write);
//实际读取的文件长度
int toCopyLength = 0;
//如果每次读取的长度小于 源文件的长度 分段读取
if (eachReadLength < fromFile.Length)
{
byte[] buffer = new byte[eachReadLength];
long copied = 0;
while (copied <= fromFile.Length - eachReadLength)
{
toCopyLength = fromFile.Read(buffer, 0, eachReadLength);
fromFile.Flush();
toFile.Write(buffer, 0, eachReadLength);
toFile.Flush();
//流的当前位置
toFile.Position = fromFile.Position;
copied += toCopyLength;
}
int left = (int)(fromFile.Length - copied);
toCopyLength = fromFile.Read(buffer, 0, left);
fromFile.Flush();
toFile.Write(buffer, 0, left);
toFile.Flush();
}
else
{
//如果每次拷贝的文件长度大于源文件的长度 则将实际文件长度直接拷贝
byte[] buffer = new byte[fromFile.Length];
fromFile.Read(buffer, 0, buffer.Length);
fromFile.Flush();
toFile.Write(buffer, 0, buffer.Length);
toFile.Flush();
}
fromFile.Close();
toFile.Close();
return true;
}
/// <summary>
/// 复制文件到路径
/// </summary>
/// <param name="file">文件,要完整路径</param>
/// <param name="dPath">目标路径</param>
/// <param name="overwrite">是否覆盖文件</param>
/// <returns></returns>
private static bool CopyFileToPath(string file, string dPath, bool overwrite)
{
bool fa = false;
try
{
if (NewFolder(dPath))
{
string destPath = Path.Combine(dPath, Path.GetFileName(file));
File.Copy(file, destPath, overwrite);
fa = true;
}
}
catch (Exception e)
{
DialogResult dr = MessageBox.Show("复制文件错误!\n" + e.Message, "惊惊盒子", MessageBoxButtons.OKCancel);
}
return fa;
}
#region 删除文件
/// <summary>
/// 删除目录
/// </summary>
/// <param name="pathWhole">全路径</param>
public static bool DelPath(string pathWhole)
{
try
{
pathWhole = StringTool.PathDelLastSlash(pathWhole);
string pathFront = StringTool.PathHigherLevel(pathWhole);
//删除所有子文件
DelDirectory(pathWhole);
//子目录和文件数都是0,才能删除母文件夹
if (Directory.GetDirectories(pathFront).Length == 0 && Directory.GetFiles(pathFront).Length == 0)
{
DirectoryInfo dir = new DirectoryInfo(pathFront)
{
Attributes = FileAttributes.Normal //设置为普通目录
};
dir.Delete(true);//删除文件夹
}
return true;
}
catch
{
return false;
}//回滚出错无需提示,可能是复制不进去
}
/// <summary>
/// 递归删除所有子路径
/// </summary>
/// <param name="sPath">来源</param>
/// <returns>是否成功</returns>
private static bool DelDirectory(string sPath)
{
bool flag = false;//是否成功删除
DirectoryInfo dir = new DirectoryInfo(sPath);//路径
DirectoryInfo[] dirs = dir.GetDirectories(); //获取所有子路径
if (dirs.Length > 0)
{
foreach (var item in dirs)//先处理子路径的文件
{
//子路径如果是文件夹,就嵌套进去
FileAttributes attr = File.GetAttributes(item.FullName);
if (attr == FileAttributes.Directory)
{
DelDirectory(item.FullName);//递归进去删除文件
}
else
{
DirectoryInfo dir2 = new DirectoryInfo(item.FullName)
{
Attributes = FileAttributes.Normal //设置为普通文件
};
dir2.Delete(true);
}
}
flag = true;
}
//最后处理主路径的文件
dir.Attributes = FileAttributes.Normal; //设置为普通文件
dir.Delete(true);//删除文件夹
return flag;
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="path">文件的路径</param>
/// <returns></returns>
public static bool DelFile(this string path)
{
bool flag = false;
if (File.Exists(path))
{
try
{
FileInfo dir = new FileInfo(path)
{
Attributes = FileAttributes.Normal //设置为普通文件
};
dir.Delete();
flag = true;
}
catch
{ }
}
return flag;
}
/// <summary>
/// 重命名文件名字,如果路径还存在就名字+1
/// </summary>
/// <param name="path">文件路径</param>
/// <returns>返回最终的名字,文件不在返回""</returns>
public static string RenameFile(this string path)
{
string str = path;
if (File.Exists(str))
{
int a = 1;
try
{
FileInfo dir = new FileInfo(str)
{
Attributes = FileAttributes.Normal //设置为普通文件
};
string qianzhui = dir.DirectoryName + "\\"; // "D:\\K01.惊惊盒子\\03.用户配置"
while (true)
{
string name = Path.GetFileNameWithoutExtension(path); //返回不带扩展名的文件名
string pathFull = qianzhui + name + a.ToString() + dir.Extension;
if (!File.Exists(pathFull))//如果没有这个文件
{
dir.MoveTo(pathFull);//就重命名这个文件名
str = pathFull;
break;
}
else
{
a++;
}
}
}
catch
{ }
}
return str;
}
#endregion
/// <summary>
/// 新建文件夹
/// </summary>
/// <param name="path">路径</param>
/// <returns>成功true,失败false</returns>
public static bool NewFolder(string path)
{
bool flag = false;
try
{
if (!Directory.Exists(path))
{
DirectoryInfo aa = Directory.CreateDirectory(path);//新建文件夹
aa.Attributes = FileAttributes.Normal;//设置文件夹属性为普通
flag = true;
}
}
catch
{ }
return flag;
}
/// <summary>
/// 路径中包含某个文件夹,有就返回文件夹路径
/// </summary>
/// <param name="dwgPath">路径</param>
/// <param name="name">文件夹名称</param>
/// <returns>成功返回含有这个文件夹名称的路径,失败返回""</returns>
public static string GetPathIncludeString(string dwgPath, string name)
{
//遍历路径中第几级有"01.饰施图"
char ca = '\\';
string[] dwgPaths = dwgPath.Split(ca);
List<string> st = new List<string>();
for (int i = 0; i < dwgPaths.Length; i++)
{
if (dwgPaths[i] == name)
{
break;
}
else
{
st.Add(dwgPaths[i]);//把前面的路径合并起来
}
}
//如果两个数组相同,表示路径没有"01.饰施图"
string[] stArr = st.ToArray();
string x = "";
if (stArr.Length != dwgPaths.Length)
{
foreach (string item in stArr)
{
x += item + "\\";
}
x += name;
}
return x;
}
/// <summary>
/// 列出本文件夹某个后缀的文件
/// </summary>
/// <param name="path">路径</param>
/// <param name="searchPattern">获取后缀的文件 *.txt</param>
/// <returns></returns>
public static string[] GetThisFolderFiles(string path, string searchPattern)
{
List<string> list = new List<string>();
DirectoryInfo theFolder = new DirectoryInfo(path);
FileInfo[] thefileInfo = theFolder.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);
foreach (FileInfo NextFile in thefileInfo) //遍历文件
{
list.Add(NextFile.FullName);
}
return list.ToArray();
}
#if false
/// <summary>
/// 获取本文件夹及其子文件夹所有后缀的文件
/// </summary>
/// <param name="path">路径</param>
/// <param name="searchPattern">获取后缀的文件 *.txt</param>
/// <returns></returns>
public static string[] GetThisFolderAndSunFiles(string path, string searchPattern)
{
List<string> list = new List<string>();
DirectoryInfo theFolder = new DirectoryInfo(path);
FileInfo[] thefileInfo = theFolder.GetFiles(searchPattern, SearchOption.AllDirectories);
foreach (FileInfo NextFile in thefileInfo) //遍历文件
{
list.Add(NextFile.FullName);
}
return list.ToArray();
}
#endif
/// <summary>
/// 获取路径下所有文件以及子文件夹中文件
/// </summary>
/// <param name="path">全路径根目录</param>
/// <param name="FileList">存放所有文件的全路径</param>
/// <param name="RelativePath"></param>
/// <returns></returns>
public static string[] GetFile(string path, string extension)
{
List<string> pas = new List<string>();
DirectoryInfo dir = new DirectoryInfo(path);
var fil = dir.GetFiles();//获取本文件夹所有文件
foreach (FileInfo f in fil)
{
if (f.Extension.ToUpper() == extension.ToUpper())
{
pas.Add(f.FullName);//保存文件路径到表中
}
}
//获取子文件夹内的文件列表,递归遍历
var dii = dir.GetDirectories();
foreach (DirectoryInfo d in dii)
{
var a = GetFile(d.FullName, extension);//返回数组
foreach (var item in a)
{
pas.Add(item);
}
}
return pas.ToArray();
}
/// <summary>
/// 判断文件是否被程序占用
/// </summary>
/// <param name="fileName">文件路径</param>
/// <returns>true表示正在使用,false没有使用</returns>
public static bool IsFileInUse(string fileName)
{
bool inUse = true;
if (File.Exists(fileName))
{
FileStream fs = null;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
inUse = false;
}
catch
{ }
finally
{
if (fs != null)
{
fs.Close();
}
}
return inUse;
}
else
{
return false;//文件不存在,肯定没有被使用
}
}
}
public static partial class FileTool
{
//https://blog.csdn.net/catchme_439/article/details/54616175
private const int FO_COPY = 0x0002;
private const int FOF_ALLOWUNDO = 0x00044;
//显示进度条 0x00044
//不显示一个进度对话框 0x0100 显示进度对话框单不显示进度条 0x0002显示进度条和对话框
private const int FOF_SILENT = 0x0002;//0x0100;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 0)]
public struct SHFILEOPSTRUCT
{
public IntPtr hwnd;
[MarshalAs(UnmanagedType.U4)]
public int wFunc;
public string pFrom;
public string pTo;
public short fFlags;
[MarshalAs(UnmanagedType.Bool)]
public bool fAnyOperationsAborted;
public IntPtr hNameMappings;
public string lpszProgressTitle;
}
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
private static extern int SHFileOperation(ref SHFILEOPSTRUCT FileOp);
public static bool ApiCopy(string strSource, string strTarget)
{
SHFILEOPSTRUCT fileop = new SHFILEOPSTRUCT
{
wFunc = FO_COPY,
pFrom = strSource.Trim(),
lpszProgressTitle = "复制大文件",
pTo = strTarget.Trim(),
//fileop.fFlags = FOF_ALLOWUNDO;
fFlags = FOF_SILENT
};
return SHFileOperation(ref fileop) == 0;
}
}
}