用C#删除程序占用文件
在写卸载程序时经常会遇到要删除文件自身的问题,此时文件被占用,使用常规方法并不容易删除。
删除文件方法如下:
文件打开时,以“共享读写模式”
1 2 3 |
FileStream inputStream = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); p.BackgroundImage = new Bitmap(inputStream); inputStream.Dispose(); |
最后给出别人写好的一个类,可以加到自己的程序中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public void WipeFile(string filename, int timesToWrite) { try { if (File.Exists(filename)) { //设置文件的属性为正常,这是为了防止文件是只读 File.SetAttributes(filename, FileAttributes.Normal); //计算扇区数目 double sectors = Math.Ceiling(new FileInfo(filename).Length / 512.0); // 创建一个同样大小的虚拟缓存 byte[] dummyBuffer = new byte[512]; // 创建一个加密随机数目生成器 RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); // 打开这个文件的FileStream FileStream inputStream = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.ReadWrite); for (int currentPass = 0; currentPass < timesToWrite; currentPass++) { // 文件流位置 inputStream.Position = 0; //循环所有的扇区 for (int sectorsWritten = 0; sectorsWritten < sectors; sectorsWritten++) { //把垃圾数据填充到流中 rng.GetBytes(dummyBuffer); // 写入文件流中 inputStream.Write(dummyBuffer, 0, dummyBuffer.Length); } } // 清空文件 inputStream.SetLength(0); // 关闭文件流 inputStream.Close(); // 清空原始日期需要 DateTime dt = new DateTime(2037, 1, 1, 0, 0, 0); File.SetCreationTime(filename, dt); File.SetLastAccessTime(filename, dt); File.SetLastWriteTime(filename, dt); // 删除文件 File.Delete(filename); } } catch (Exception) { } } |
自己写了一个新的文章https://tson.com/csharp-uninstall-self/,再次说明了这个问题,有兴趣的可以去看看。
好好看了一下,上面的代码不是删除占用文件的代码,而是彻底删除文件的代码。在将文件删除后在原有扇区写入随机数,文件就无法恢复了。
我遇到的问题是这样的,想写一个卸载程序,最终也把自己删除掉。最后找了一个办法是用批处理文件,如果我们遇到的问题一样,你也可以尝试一下。
事实证明上面的方法是不正确的。
FileStream inputStream = new FileStream(filename, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
这一句如果文件被占用,那么会出错。如果将FileAccess.Write改正FileAccess.Read是能够打开,但是无法对流写入。总之会出错。