C#对下载的代码的资源文件(如.resx)批量解锁

资源文件被锁定的解决方案:

在项目代码文件从一台电脑A转移到另一台电脑B时,电脑B运行程序,就会报resx文件错误

原因:

资源文件.resx被锁定了,此时 单击“解除锁定”按钮可以取消锁定。

可以直接删除该.resx文件【.resx文件本质是一种xml配置文件】

右键锁定的资源文件,点击“属性”按钮,然后 点击“解除锁定”即可

 

如果是这样的资源文件(.resx)较少,可以每个文件都点击下“解除锁定”,

但锁定的资源文件很多,一个一个解除锁定会吐血的。

下面寻找批量解除锁定的方案:

参考微软文档:

https://docs.microsoft.com/zh-cn/sysinternals/downloads/streams

从这个地址下载

Streams.zip 并解压到bin\debug\Streams 下

运行文件bin\debug\Streams\streams64.exe

新建Winform应用程序FormBatchUnlock,将默认的Form1重命名为FormBatchUnlock.cs,

窗体设计如图:

FormBatchUnlock.cs源程序如下【忽略设计器自动生成的代码】:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BatchUnlockResFileDemo
{
    public partial class FormBatchUnlock : Form
    {
        public FormBatchUnlock()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 递归解除指定目录(文件夹)下的所有资源文件的锁定状态
        /// </summary>
        /// <param name="filePath">指定的目录</param>
        /// <returns></returns>
        private string UnlockFile(string filePath)
        {
            /*
             使用CMD命令
             参考文档:
             https://docs.microsoft.com/zh-cn/sysinternals/downloads/streams
             需要下载 [Streams\\streams64.exe]文件
             -d 针对文件或文件夹执行
             -s -d 可以递归执行文件夹下的子文件\子文件夹
            */
            string output = string.Empty;
            //string cmd = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "streams64.exe") + "-d \"C:\\Users\\ylq\\abcd.rar\"" + "&exit";      
            string cmd = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Streams\\streams64.exe") + $" -d \"{filePath}\"" + "&exit";
            using (Process p = new Process())
            {
                string cmdPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe");
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.Arguments = "/c " + cmdPath;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.Verb = "RunAs";
                p.Start();
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush = true;
                output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();//等待程序执行完,退出进程
                p.Close();
            }            
            return output;
        }

        private void btnSelectFolder_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            if (DialogResult.OK == folderBrowserDialog.ShowDialog())
            {
                txtFolderPath.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void btnUnlock_Click(object sender, EventArgs e)
        {
            //string path = txtFilePath.Text.Trim();
            string path = txtFolderPath.Text.Trim();
            if (!Directory.Exists(path))
            {
                MessageBox.Show("指定或选择的目录不存在", "错误");
                return;
            }
            try
            {
                List<string> list = GetAllResxFile(path);
                MessageBox.Show($"开始解除resx文件的锁定状态...需解除个数【{list.Count}】", $"开始解除【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】");
                string outputResult = string.Empty;
                for (int i = 0; i < list.Count; i++)
                {
                    outputResult = UnlockFile(list[i]);
                }                
                MessageBox.Show($"批量解除锁定成功.\n最后的内容【{outputResult}】\n解除锁定的源目录【{path}】\n", $"批量解除锁定完成【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "操作出现异常");
            }
        }

        /// <summary>
        /// 获取指定目录(遍历子目录)下的所有resx文件,放入到集合中
        /// </summary>
        /// <param name="folderPath"></param>
        /// <returns></returns>
        private List<string> GetAllResxFile(string folderPath)
        {
            List<string> list = new List<string>();
            Queue<string> queue = new Queue<string>();
            queue.Enqueue(folderPath);
            while (queue.Count > 0)
            {
                //获取当前目录
                string currentFolder = queue.Dequeue();
                string[] fileArray = Directory.GetFiles(currentFolder);
                for (int i = 0; i < fileArray.Length; i++)
                {
                    if (Path.GetExtension(fileArray[i]).ToLower() == ".resx")
                    {
                        list.Add(fileArray[i]);
                    }
                }                
                string[] directoryArray = Directory.GetDirectories(currentFolder);
                for (int i = 0; i < directoryArray.Length; i++)
                {
                    queue.Enqueue(directoryArray[i]);
                }
            }
            return list;
        }
    }
}

测试运行效果如图:

等待一段时间,即可批量完成:

Guess you like

Origin blog.csdn.net/ylq1045/article/details/115751410