资源文件被锁定的解决方案:
在项目代码文件从一台电脑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;
}
}
}
测试运行效果如图:
等待一段时间,即可批量完成: