问题描述
除了使用Process.Exited(){}事件之外,是否有其他方法可以确定何时不再使用文件并测试文件是否被锁定?是否有某种模式或某些我们不使用的命令可以更好地处理此问题?
当前,我们在用户的temp文件夹中创建文件,在其默认程序(由文件扩展名确定)中启动文件,然后对文件进行更新(如果有更改),并在关闭后删除。
这对于所有单个文件启动都很好。
但是,在某些程序(例如Gimp,Word或Paint.net)中打开第二个或多个文件时,我们遇到了问题。他们打开文件,然后将文件Handle传递给现有流程,关闭作为以下提交流程创建的初始流程。由于原始进程(文件进程)已关闭,因此Exited事件会过早触发。
如果将以下代码放入控制台应用程序项目的Program.cs中,并将路径和文件名更改为现有文件。您可以运行它,并且该文件应在其默认查看器/编辑器中打开。可能需要选择默认程序。
我们用Word和GIMP对此进行了测试,以确保可以正常工作。确保关闭所有WinWord进程(或将要测试的文件设置为默认值的程序的任何进程),并在退出事件中运行带有断点的程序。您会注意到,只有在程序关闭且文件未锁定时,它才会命中。
但是,如果您有Word文档或上述任何其他程序,请打开然后运行该程序,您会发现打开文档后立即触发Exited事件。对于Word Documents,该文件被锁定,但是对于GIMP,该文件未被锁定。因此,仅确定退出过程时文件是否被锁定是不够的。
因此,如果它是唯一运行的进程,或者它是保留我们创建的进程的程序,则没有问题。诸如NotePad之类的程序会保持打开每个文件的过程,并且Exited事件会按预期触发。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ExampleConsole
{
class Program
{
List<FileSystemWatcher> FileWatchers { get; set; } = new List<FileSystemWatcher>();
static public bool IsFileChanged { get; set; }
//replace the following with whatever file you prefer,but GIMP,Word,Paint.Net,and FoxIt PDF Editor
//are what we have noticed using a single manager processes rather than the process that ran when opening the file.
static string fileName = "source.gif";
static string myTempFile = Path.Combine(Path.GetTempPath() + fileName);
[STAThread]
static void Main()
{
Process fileProcess = Process.Start(new processstartinfo(myTempFile)
{
UseShellExecute = true,CreateNowindow = true
});
fileProcess.EnableRaisingEvents = true;
//This is where the issue occurs launching more than 1 Gimp/Word/FoxIt PDF Editor,//the "Exited" Event runs when the process that opened the file closes after handing off to a manager process
fileProcess.Exited += (o,args) =>
{
if (CheckFileLock(myTempFile))
{
MessageBox.Show("File is locked.");
}
else
{
MessageBox.Show("File is not locked.");
}
//If the process exits,we read the changes into memory and save to our database.
if (IsFileChanged)
{
MessageBox.Show("File would be saved.");
}
fileProcess?.dispose();
};
#if DEBUG
try
{
//...
}
finally
{
Console.WriteLine("Press enter to close...");
Console.ReadLine();
}
#endif
}
public static bool CheckFileLock(string filePath)
{
try
{
using (File.Open(filePath,FileMode.Open)) { }
}
catch (IOException e)
{
var errorCode = Marshal.GetHRForException(e) & ((1 << 16) - 1);
return errorCode == 32 || errorCode == 33;
}
return false;
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)