2010年9月17日 星期五

刪除被鎖定的檔案

如果你是尋找可以立即使用的軟體,那這篇對你無用
這篇是針對如何使用程式刪除檔案的筆記 (意思就是我看了但還沒測試 :p

原始網頁 http://stackoverflow.com/questions/317071/how-do-i-find-out-which-process-is-locking-a-file-c

1. 使用MS的Handle v3.42工具輔助
下載http://technet.microsoft.com/en-us/sysinternals/bb896655.aspx
使用以下程式碼呼叫

 string fileName = @"c:\aaa.doc";//Path to locked file

                Process tool = new Process();
                tool.StartInfo.FileName = "handle.exe";
                tool.StartInfo.Arguments = fileName;
                tool.StartInfo.UseShellExecute = false;
                tool.StartInfo.RedirectStandardOutput = true;
                tool.Start();                   
                tool.WaitForExit();
                string outputTool = tool.StandardOutput.ReadToEnd();

                string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
                foreach(Match match in Regex.Matches(outputTool, matchPattern))
                {
                        Process.GetProcessById(int.Parse(match.Value)).Kill();
                }

2. 取得process陣列,判斷是哪各process鎖定檔案
不過原作者說這作法無法取得txt之類的鎖定來源


using System.Management; using System.IO;   
static class Module1 { static internal ArrayList myProcessArray = new ArrayList(); private static Process myProcess; 
public static void Main() { 

    string strFile = "c:\\windows\\system32\\msi.dll"; 
    ArrayList a = getFileProcesses(strFile); 
    foreach (Process p in a) { 
        Debug.Print(p.ProcessName); 
    } }
private static ArrayList getFileProcesses(string strFile) { 
    myProcessArray.Clear(); 
    Process[] processes = Process.GetProcesses; 
    int i = 0; 
    for (i = 0; i <= processes.GetUpperBound(0) - 1; i++) { 
        myProcess = processes(i); 
        if (!myProcess.HasExited) { 
            try { 
                ProcessModuleCollection modules = myProcess.Modules; 
                int j = 0; 
                for (j = 0; j <= modules.Count - 1; j++) { 
                    if ((modules.Item(j).FileName.ToLower.CompareTo(strFile.ToLower) == 0)) { 
                        myProcessArray.Add(myProcess); 
                        break; // TODO: might not be correct. Was : Exit For 
                    } 
                } 
            } 
            catch (Exception exception) { 
            } 
            //MsgBox(("Error : " & exception.Message)) 
        } 
    } 
    return myProcessArray; } }


3.算是進階版?
using System;
using System.Collections;
using System.Diagnostics;
using System.Management;
using System.IO;
static class Module1
{
    static internal ArrayList myProcessArray = new ArrayList();
    private static Process myProcess;

    public static void Main()
    {
        string strFile = "c:\\windows\\system32\\msi.dll";
        ArrayList a = getFileProcesses(strFile);
        foreach (Process p in a)
        {
            Debug.Print(p.ProcessName);
        }
    }

    private static ArrayList getFileProcesses(string strFile)
    {
        myProcessArray.Clear();
        Process[] processes = Process.GetProcesses();
        int i = 0;
        for (i = 0; i <= processes.GetUpperBound(0) - 1; i++)
        {
            myProcess = processes[i];
            //if (!myProcess.HasExited) //This will cause an "Access is denied" error
            if (myProcess.Threads.Count > 0)
            {
                try
                {
                    ProcessModuleCollection modules = myProcess.Modules;
                    int j = 0;
                    for (j = 0; j <= modules.Count - 1; j++)
                    {
                        if ((modules[j].FileName.ToLower().CompareTo(strFile.ToLower()) == 0))
                        {
                            myProcessArray.Add(myProcess);
                            break;
                            // TODO: might not be correct. Was : Exit For
                        }
                    }
                }
                catch (Exception exception)
                {
                    //MsgBox(("Error : " & exception.Message)) 
                }
            }
        }

        return myProcessArray;
    }
}

沒有留言: