最近碰到一个需求,删除Office(Word,Excel,PowerPoint)中Recent Document最近文档地址不存在的文件,即每次打开office(Word,Excel,PowerPoint),发现Recent Document有些文件的地址已经失效(移动或者删除),怎么把这些无效的文件删除,这里把我的做法,思路以及碰到的问题和解决过程记录下来。
1.通过注册表找到Office(Word,Excel,PowerPoint)中Recent Document中对应的位置,这里以Word为例,最近文件有file1,file2,file3,对应打开的位置为(C:\Test\file1.doc,C:\Test\file2.doc,C:\Test\file3.doc),其中file2已经移动
//OpenSubKey(param1,param2),param1注册表中相对路径,param2为true代表有Write的权限
//version是Word(Excel,PowerPoint)的版本,例如2013的版本,对应注册表的目录为15.0
//officeType是Office工具的类型,这里应该是Word
RegistryKey userMRU = Registry.CurrentUser.OpenSubKey(string.Format("Software\\Microsoft\\Office\\{0}\\{1}\\User MRU", version, officeType), true);
2.注册表User MRU目录下面是Word所有用户的信息,其中Recent Document保存在对应用户的子目录File MRU下面,下面遍历得到具体某个用户的File MRU
//得到userMRU所有子文件夹的name,即对应不同的用户
string[] directoryNames = userMRU.GetSubKeyNames();
//遍历得到不同用户下面的File MRU文件夹
foreach (string directoryName in directoryNames)
{
RegistryKey userMRUSubDirectory = userMRU.OpenSubKey(directoryName, true);
RegistryKey fileMRU = userMRUSubDirectory.OpenSubKey("File MRU", true);
}
3.需要得到fileMRU下面的key和value,并且判断value中存储的文件路径是否还存在
//得到fileMRU下面所有key的Name,分别为item1,item2,item3
string[] fileTitles = fileMRU.GetValueNames();
//得到key的value,例如[F00000000][T01D45490CE43CA41][O00000000]*C:\Test\File1.doc
//*前面是一段我们暂时用不到的东西,我们需要的是*后面的文件路径
string fileValue = fileMRU.GetValue(fileTitles[i]).ToString();
string[] fileValues = fileValue.Split('*');
//判断fileValues[fileValues.Length-1]是否存在这个路径的文件
//这里不用fileValues[1]判断,防止用户自己到注册表手动改value导致value失效,程序就会抛异常
if (!File.Exists(fileValues[fileValues.Length-1]))
{
}
4.下面就是当文件路径下面的文件已经不存在了,该如何修改
(思路1)最开始的时候是直接删除key,发现file2不存在,删除item2,f5刷新注册表,会发现注册表中只有item1和item3,似乎成功删除了,但是打开word工具就会发现最近文档只有item1对应的file1,注册表中item3读取不到了(这里简单说一下我的个人理解,当最近文档中有item1,对应文件file1,注册表为key:item1,value:一段string*file1的路径,这时候word打开一个文件,最近文档就增加了file2,注册表就变成了key:item1,value:一段string*file2的路径;key:item2,value:一段string*file1的路径,即可以理解word读取注册表中key是从上往下读取的,如果某一个key不存在后面的key就不继续读取了)
//删除file2对应的key
fileMRU.DeleteValue(fileTitles[i]);
(思路2)直接删除key不行,那就改变key的值,让其为空,改过之后打开word能正常读取,但是这里也留下来一个隐患,注册表中还有三个key,Recent Document则只有两个文件file1,file3。file2不存在了,但是它还占用着一个key,关键是它不知道它占用着哪个key的资源,随着像file2这种失效文件的增多,恐怖的事情就会发生了
//修改file2对应的key的值
fileMRU.SetValue(fileTitles[i],"");
(思路三)把item2中value改成已经存在item3中有效的value,然后删除后面的item3,这样就完美的解决了问题
string[] fileTitles = fileMRU.GetValueNames();
// tempLength用来记录有效的key的数目,这样每次删除key都是最后一个
// 不会数组越界
//要逆序操作,例如item3,item2,item1,这样每次碰到无效的key,只要把后面的
//key(已经判断是有效)的value赋给前一个key,然后删除最后一个key即可
int tempLength = fileTitles.Length;
for (int i = tempLength-1; i >= 0; i--)
{
string fileValue = fileMRU.GetValue(fileTitles[i]).ToString();
string[] fileValues = fileValue.Split('*');
if (!File.Exists(fileValues[fileValues.Length-1]))
{
try
{
for (int j = i + 1; j < tempLength; j++)
{
string value = fileMRU.GetValue(fileTitles[j]).ToString();
fileMRU.SetValue(fileTitles[j - 1], value);
}
fileMRU.DeleteValue(fileTitles[tempLength-1]);
tempLength--;
}
catch (System.Exception ex)
{
//你可以打印日志或者输出控制台
}
}
}
5.问题解决,提交代码