From comments, a test with IFileIsInUse and GetInfoForFileInUse
to get the executable locking a file
As it returns only the friendly name, I added code to get the .exe from this name : maybe it needs to be improved....
// To lock an image file
//string sFile = @"E:\Hulk.png";
//pictureBox1.Image = System.Drawing.Image.FromFile(sFile);
// Notepad does not lock the file
// Wordpad locks the file
//string sFile = @"E:\test.txt";
// Winword locks the file
string sFile = @"E:\test.doc";
// Adobe locks the file
//string sFile = @"E:\test.pdf";
IShellItem pShellItem = null;
IFileIsInUse pFileIsInUse = null;
HRESULT hr = SHCreateItemFromParsingName(sFile, IntPtr.Zero, typeof(IShellItem).GUID, out pShellItem);
if (hr == HRESULT.S_OK)
{
hr = GetInfoForFileInUse(pShellItem, out pFileIsInUse);
if (hr == HRESULT.S_OK)
{
StringBuilder sbString = new StringBuilder(260);
hr = pFileIsInUse.GetAppName(out sbString);
if (hr == HRESULT.S_OK)
{
uint nFlags = 0;
hr = pFileIsInUse.GetCapabilities(out nFlags);
string sRightProcessPath = null;
string sProcessPath = null;
foreach (var procs in System.Diagnostics.Process.GetProcesses())
{
int nPID = procs.Id;
IntPtr hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, nPID);
if (hProcess != IntPtr.Zero)
{
uint nSize = 260;
StringBuilder sProcessImageName = new StringBuilder((int)nSize);
QueryFullProcessImageName(hProcess, 0, sProcessImageName, ref nSize);
sProcessPath = sProcessImageName.ToString();
CloseHandle(hProcess);
}
if (sProcessPath != null)
{
try
{
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(sProcessPath);
string sFileDescription = fvi.FileDescription;
if (sFileDescription != null)
{
if (sFileDescription.ToLower().Contains(sbString.ToString().ToLower()))
{
sRightProcessPath = sProcessPath;
break;
}
}
}
catch (Exception Ex)
{
string sText = Convert.ToString(Ex);
}
}
}
string sMessage = "Application : " + sbString.ToString();
if (sRightProcessPath != null)
sMessage += Environment.NewLine + "Process path : " + sRightProcessPath;
System.Windows.Forms.MessageBox.Show(sMessage, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
string sMessage = sFile + " not locked";
System.Windows.Forms.MessageBox.Show(sMessage, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
Declarations :
public enum HRESULT : int
{
S_OK = 0,
S_FALSE = 1,
E_NOINTERFACE = unchecked((int)0x80004002),
E_NOTIMPL = unchecked((int)0x80004001),
E_FAIL = unchecked((int)0x80004005),
E_UNEXPECTED = unchecked((int)0x8000FFFF),
E_OUTOFMEMORY = unchecked((int)0x8007000E)
}
[DllImport("Windows.storage.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern HRESULT GetInfoForFileInUse(IShellItem psi, out IFileIsInUse ppof);
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
public interface IShellItem
{
HRESULT BindToHandler(IntPtr pbc, ref Guid bhid, ref Guid riid, ref IntPtr ppv);
HRESULT GetParent(ref IShellItem ppsi);
[PreserveSig]
HRESULT GetDisplayName(SIGDN sigdnName, ref System.Text.StringBuilder ppszName);
HRESULT GetAttributes(uint sfgaoMask, ref uint psfgaoAttribs);
HRESULT Compare(IShellItem psi, uint hint, ref int piOrder);
}
public enum SIGDN : int
{
SIGDN_NORMALDISPLAY = 0x0,
SIGDN_PARENTRELATIVEPARSING = unchecked((int)0x80018001),
SIGDN_DESKTOPABSOLUTEPARSING = unchecked((int)0x80028000),
SIGDN_PARENTRELATIVEEDITING = unchecked((int)0x80031001),
SIGDN_DESKTOPABSOLUTEEDITING = unchecked((int)0x8004C000),
SIGDN_FILESYSPATH = unchecked((int)0x80058000),
SIGDN_URL = unchecked((int)0x80068000),
SIGDN_PARENTRELATIVEFORADDRESSBAR = unchecked((int)0x8007C001),
SIGDN_PARENTRELATIVE = unchecked((int)0x80080001)
}
[ComImport()]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("64a1cbf0-3a1a-4461-9158-376969693950")]
public interface IFileIsInUse
{
[PreserveSig]
HRESULT GetAppName(out StringBuilder ppszName);
HRESULT GetUsage(out FILE_USAGE_TYPE pfut);
HRESULT GetCapabilities(out uint pdwCapFlags);
[PreserveSig]
HRESULT GetSwitchToHWND(out IntPtr phwnd);
HRESULT CloseFile();
}
public enum FILE_USAGE_TYPE
{
FUT_PLAYING = 0,
FUT_EDITING = (FUT_PLAYING + 1),
FUT_GENERIC = (FUT_EDITING + 1)
}
[DllImport("Shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern HRESULT SHCreateItemFromParsingName(string pszPath, IntPtr pbc, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
public const int PROCESS_QUERY_LIMITED_INFORMATION = (0x1000);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, int dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CloseHandle(IntPtr hObject);