c# - How to find and kill a process who cause ioException? -


i tried several solutions find process locking file , kill process. found solution works fine crashes application , don't know why. @ example , please if me, appreciated.

try {     file.copyto(destabsolutepath, true); } catch (ioexception ioexception) {     foreach (var process in process.getprocessesbyname(file.name.replace(path.getextension(file.name), "")))     {         process.kill();         process.waitforexit();     }     foreach (process p in win32processes.getprocesseslockingfile(file.fullname))     {         p.kill();         process.waitforexit();     }     file.copyto(destabsolutepath, true); } 

and code used base on post: using c#, how 1 figure out process locked file?

i modified getprocesseslockingfile() method work me. explained reason in last comment of post (link above). maybe didn't use well.

public static class win32processes {     /// <summary>     /// return list of processes hold on given file.     /// </summary>     public static list<process> getprocesseslockingfile(string filepath)     {         var procs = new list<process>();          var processlistsnapshot = process.getprocesses();         foreach (var process in processlistsnapshot)         {             if (process.id <= 4) { continue; } // system processes             list<string> paths = getfileslockedby(process);             foreach (string path in paths)             {                 string pathdirectory = path;                 if (!pathdirectory.endswith(constants.double_backslash))                 {                     pathdirectory = pathdirectory + constants.double_backslash;                 }                 string lastfoldername = path.getfilename(path.getdirectoryname(pathdirectory));                  if (filepath.contains(lastfoldername))                 {                     procs.add(process);                 }              }         }         return procs;     }      /// <summary>     /// return list of file locks held process.     /// </summary>     public static list<string> getfileslockedby(process process)     {         var outp = new list<string>();          threadstart ts = delegate         {             try             {                 outp = unsafegetfileslockedby(process);             }             catch { ignore(); }         };           try         {             var t = new thread(ts);             t.isbackground = true;             t.start();             if (!t.join(250))             {                 try                 {                     t.interrupt();                     t.abort();                 }                 catch { ignore(); }             }         }         catch { ignore(); }          return outp;     }       #region inner workings     private static void ignore() { }     private static list<string> unsafegetfileslockedby(process process)     {         try         {             var handles = gethandles(process);             var files = new list<string>();              foreach (var handle in handles)             {                 var file = getfilepath(handle, process);                 if (file != null) files.add(file);             }              return files;         }         catch         {             return new list<string>();         }     }      const int cnst_system_handle_information = 16;     private static string getfilepath(win32api.system_handle_information systemhandleinformation, process process)     {         var ipprocesshwnd = win32api.openprocess(win32api.processaccessflags.all, false, process.id);         var objbasic = new win32api.object_basic_information();         var objobjecttype = new win32api.object_type_information();         var objobjectname = new win32api.object_name_information();         var strobjectname = "";         var nlength = 0;         intptr iptemp, iphandle;          if (!win32api.duplicatehandle(ipprocesshwnd, systemhandleinformation.handle, win32api.getcurrentprocess(), out iphandle, 0, false, win32api.duplicate_same_access))             return null;          intptr ipbasic = marshal.allochglobal(marshal.sizeof(objbasic));         win32api.ntqueryobject(iphandle, (int)win32api.objectinformationclass.objectbasicinformation, ipbasic, marshal.sizeof(objbasic), ref nlength);         objbasic = (win32api.object_basic_information)marshal.ptrtostructure(ipbasic, objbasic.gettype());         marshal.freehglobal(ipbasic);          intptr ipobjecttype = marshal.allochglobal(objbasic.typeinformationlength);         nlength = objbasic.typeinformationlength;         // 1 never locks...         while ((uint)(win32api.ntqueryobject(iphandle, (int)win32api.objectinformationclass.objecttypeinformation, ipobjecttype, nlength, ref nlength)) == win32api.status_info_length_mismatch)         {             if (nlength == 0)             {                 console.writeline("nlength returned @ zero! ");                 return null;             }             marshal.freehglobal(ipobjecttype);             ipobjecttype = marshal.allochglobal(nlength);         }          objobjecttype = (win32api.object_type_information)marshal.ptrtostructure(ipobjecttype, objobjecttype.gettype());         if (is64bits())         {             iptemp = new intptr(convert.toint64(objobjecttype.name.buffer.tostring(), 10) >> 32);         }         else         {             iptemp = objobjecttype.name.buffer;         }           var strobjecttypename = marshal.ptrtostringuni(iptemp, objobjecttype.name.length >> 1);         marshal.freehglobal(ipobjecttype);         if (strobjecttypename != "file")             return null;          nlength = objbasic.nameinformationlength;          var ipobjectname = marshal.allochglobal(nlength);          // ...this call hangs. windows error.         while ((uint)(win32api.ntqueryobject(iphandle, (int)win32api.objectinformationclass.objectnameinformation, ipobjectname, nlength, ref nlength)) == win32api.status_info_length_mismatch)         {             marshal.freehglobal(ipobjectname);             if (nlength == 0)             {                 console.writeline("nlength returned @ zero! " + strobjecttypename);                 return null;             }             ipobjectname = marshal.allochglobal(nlength);         }         objobjectname = (win32api.object_name_information)marshal.ptrtostructure(ipobjectname, objobjectname.gettype());          if (is64bits())         {             iptemp = new intptr(convert.toint64(objobjectname.name.buffer.tostring(), 10) >> 32);         }         else         {             iptemp = objobjectname.name.buffer;         }          if (iptemp != intptr.zero)         {              var batemp = new byte[nlength];             try             {                 marshal.copy(iptemp, batemp, 0, nlength);                  strobjectname = marshal.ptrtostringuni(is64bits() ? new intptr(iptemp.toint64()) : new intptr(iptemp.toint32()));             }             catch (accessviolationexception)             {                 return null;             }                         {                 marshal.freehglobal(ipobjectname);                 win32api.closehandle(iphandle);             }         }          string path = getregularfilenamefromdevice(strobjectname);         try         {             return path;         }         catch         {             return null;         }     }      private static string getregularfilenamefromdevice(string strrawname)     {         string strfilename = strrawname;         foreach (string strdrivepath in environment.getlogicaldrives())         {             var sbtargetpath = new stringbuilder(win32api.max_path);             if (win32api.querydosdevice(strdrivepath.substring(0, 2), sbtargetpath, win32api.max_path) == 0)             {                 return strrawname;             }             string strtargetpath = sbtargetpath.tostring();             if (strfilename.startswith(strtargetpath))             {                 strfilename = strfilename.replace(strtargetpath, strdrivepath.substring(0, 2));                 break;             }         }         return strfilename;     }      private static ienumerable<win32api.system_handle_information> gethandles(process process)     {         var nhandleinfosize = 0x10000;         var iphandlepointer = marshal.allochglobal(nhandleinfosize);         var nlength = 0;         intptr iphandle;          while (win32api.ntquerysysteminformation(cnst_system_handle_information, iphandlepointer, nhandleinfosize, ref nlength) == win32api.status_info_length_mismatch)         {             nhandleinfosize = nlength;             marshal.freehglobal(iphandlepointer);             iphandlepointer = marshal.allochglobal(nlength);         }          var batemp = new byte[nlength];         marshal.copy(iphandlepointer, batemp, 0, nlength);          long lhandlecount;         if (is64bits())         {             lhandlecount = marshal.readint64(iphandlepointer);             iphandle = new intptr(iphandlepointer.toint64() + 8);         }         else         {             lhandlecount = marshal.readint32(iphandlepointer);             iphandle = new intptr(iphandlepointer.toint32() + 4);         }          var lsthandles = new list<win32api.system_handle_information>();          (long lindex = 0; lindex < lhandlecount; lindex++)         {             var shhandle = new win32api.system_handle_information();             if (is64bits())             {                 shhandle = (win32api.system_handle_information)marshal.ptrtostructure(iphandle, shhandle.gettype());                 iphandle = new intptr(iphandle.toint64() + marshal.sizeof(shhandle) + 8);             }             else             {                 iphandle = new intptr(iphandle.toint64() + marshal.sizeof(shhandle));                 shhandle = (win32api.system_handle_information)marshal.ptrtostructure(iphandle, shhandle.gettype());             }             if (shhandle.processid != process.id) continue;             lsthandles.add(shhandle);         }         return lsthandles;      }      private static bool is64bits()     {         return marshal.sizeof(typeof(intptr)) == 8;     }      internal class win32api     {         [dllimport("ntdll.dll")]         public static extern int ntqueryobject(intptr objecthandle, int             objectinformationclass, intptr objectinformation, int objectinformationlength,             ref int returnlength);          [dllimport("kernel32.dll", setlasterror = true)]         public static extern uint querydosdevice(string lpdevicename, stringbuilder lptargetpath, int ucchmax);          [dllimport("ntdll.dll")]         public static extern uint ntquerysysteminformation(int             systeminformationclass, intptr systeminformation, int systeminformationlength,             ref int returnlength);          [dllimport("kernel32.dll")]         public static extern intptr openprocess(processaccessflags dwdesiredaccess, [marshalas(unmanagedtype.bool)] bool binherithandle, int dwprocessid);         [dllimport("kernel32.dll")]         public static extern int closehandle(intptr hobject);         [dllimport("kernel32.dll", setlasterror = true)]         [return: marshalas(unmanagedtype.bool)]         public static extern bool duplicatehandle(intptr hsourceprocesshandle,            ushort hsourcehandle, intptr htargetprocesshandle, out intptr lptargethandle,            uint dwdesiredaccess, [marshalas(unmanagedtype.bool)] bool binherithandle, uint dwoptions);         [dllimport("kernel32.dll")]         public static extern intptr getcurrentprocess();          public enum objectinformationclass         {             objectbasicinformation = 0,             objectnameinformation = 1,             objecttypeinformation = 2,             objectalltypesinformation = 3,             objecthandleinformation = 4         }          [flags]         public enum processaccessflags : uint         {             = 0x001f0fff,             terminate = 0x00000001,             createthread = 0x00000002,             vmoperation = 0x00000008,             vmread = 0x00000010,             vmwrite = 0x00000020,             duphandle = 0x00000040,             setinformation = 0x00000200,             queryinformation = 0x00000400,             synchronize = 0x00100000         }          [structlayout(layoutkind.sequential)]         public struct object_basic_information         { // information class 0             public int attributes;             public int grantedaccess;             public int handlecount;             public int pointercount;             public int pagedpoolusage;             public int nonpagedpoolusage;             public int reserved1;             public int reserved2;             public int reserved3;             public int nameinformationlength;             public int typeinformationlength;             public int securitydescriptorlength;             public system.runtime.interopservices.comtypes.filetime createtime;         }          [structlayout(layoutkind.sequential)]         public struct object_type_information         { // information class 2             public unicode_string name;             public int objectcount;             public int handlecount;             public int reserved1;             public int reserved2;             public int reserved3;             public int reserved4;             public int peakobjectcount;             public int peakhandlecount;             public int reserved5;             public int reserved6;             public int reserved7;             public int reserved8;             public int invalidattributes;             public generic_mapping genericmapping;             public int validaccess;             public byte unknown;             public byte maintainhandledatabase;             public int pooltype;             public int pagedpoolusage;             public int nonpagedpoolusage;         }          [structlayout(layoutkind.sequential)]         public struct object_name_information         { // information class 1             public unicode_string name;         }          [structlayout(layoutkind.sequential, pack = 1)]         public struct unicode_string         {             public ushort length;             public ushort maximumlength;             public intptr buffer;         }          [structlayout(layoutkind.sequential)]         public struct generic_mapping         {             public int genericread;             public int genericwrite;             public int genericexecute;             public int genericall;         }          [structlayout(layoutkind.sequential, pack = 1)]         public struct system_handle_information         { // information class 16             public int processid;             public byte objecttypenumber;             public byte flags; // 0x01 = protect_from_close, 0x02 = inherit             public ushort handle;             public int object_pointer;             public uint32 grantedaccess;         }          public const int max_path = 260;         public const uint status_info_length_mismatch = 0xc0000004;         public const int duplicate_same_access = 0x2;         public const uint file_sequential_only = 0x00000004;     }     #endregion } 


Comments