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
Post a Comment