www.pudn.com > FileLockerApplication.zip > FileLocker.cs, change:2008-05-09,size:16252b


´╗┐using System; 
using System.IO; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Runtime.InteropServices.ComTypes; 
using System.Security; 
using Microsoft.Win32; 
 
namespace LukeSw.IO 
{ 
    /// <summary> 
    /// Provides a way of notifying Windows Explorer, which files are currently used by the application. 
    /// </summary> 
    public sealed class FileLocker : IDisposable, NativeMethods.IOleObject 
    { 
        #region " Registering and Unregistering " 
 
        /// <summary> 
        /// Registers the FileLocker. Invoke it from the application during the installation process. 
        /// </summary> 
        /// <exception cref="T:System.InvalidOperationException">The attempt to register the FileLocker is invalid because the attempt to modify the registry is denied or the process executable has an invalid location.</exception> 
        public static void Register() 
        { 
            try 
            { 
                string guid = GetAssemblyGuid(); 
                string progid = GetAssemblyProgId(); 
                string location = GetAssemblyLocation(); 
 
                Registry.ClassesRoot.CreateSubKey(@"CLSID\" + guid + @"\ProgID").SetValue(null, progid); 
                Registry.ClassesRoot.CreateSubKey(progid + @"\CLSID").SetValue(null, guid); 
                Registry.ClassesRoot.CreateSubKey(progid + @"\shell\Open\command").SetValue(null, "\"" + location + "\""); 
            } 
            catch (Exception e) 
            { 
                throw new InvalidOperationException("Cannot register FileLocker.", e); 
            } 
        } 
 
        /// <summary> 
        /// Unregisters the FileLocker. Invoke it from the application during the uninstallation process. 
        /// </summary> 
        /// <exception cref="T:System.InvalidOperationException">The attempt to unregister the FileLocker is invalid because the attempt to modify the registry is denied or the process executable has an invalid location.</exception> 
        public static void Unregister() 
        { 
            try 
            { 
                string guid = GetAssemblyGuid(); 
                string progid = GetAssemblyProgId(); 
                string location = GetAssemblyLocation(); 
 
                Registry.ClassesRoot.OpenSubKey(@"CLSID", true).DeleteSubKeyTree(guid); 
                Registry.ClassesRoot.DeleteSubKeyTree(progid); 
                Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\ShellNoRoam\MUICache", true).DeleteValue(location, false); 
            } 
            catch (Exception e) 
            { 
                throw new InvalidOperationException("Cannot unregister FileLocker.", e); 
            } 
        } 
 
        private static string GetAssemblyLocation() 
        { 
            string location = Assembly.GetEntryAssembly().Location; 
            if (!File.Exists(location)) 
            { 
                throw new FileNotFoundException(); 
            } 
            return location; 
        } 
 
        private static string GetAssemblyGuid() 
        { 
            return "{" + _GetAssemblyGuid() + "}"; 
        } 
 
        private static string GetAssemblyProgId() 
        { 
            return "LukeSw.IO.FileLocker." + _GetAssemblyGuid(); 
        } 
 
        private static Guid _GetAssemblyGuid() 
        { 
            object[] attrs = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), false); 
            Guid? g = null; 
            foreach (object attr in attrs) 
            { 
                if (attr is GuidAttribute) 
                { 
                    g = new Guid((attr as GuidAttribute).Value); 
                } 
            } 
            if (g == null) 
            { 
                throw new InvalidOperationException("Assembly has no GuidAttribute attribute applied to it."); 
            } 
            return g.Value; 
        } 
 
        #endregion 
 
        #region " Locking & Unlocking " 
 
        /// <summary> 
        /// Initializes a new instance of the <see cref="FileLocker"/> class and notifies the Windows Explorer that the specified file is currently used by the application. 
        /// </summary> 
        /// <param name="fileInfo">The used file's FileInfo.</param> 
        /// <exception cref="T:System.IO.FileNotFoundException"/> 
        /// <exception cref="T:System.InvalidOperationException">Attempt to notify of file usage was unsuccessful.</exception> 
        public FileLocker(FileInfo fileInfo) : this(fileInfo.FullName) { } 
 
        /// <summary> 
        /// Initializes a new instance of the <see cref="FileLocker"/> class and notifies the Windows Explorer that the specified file is currently used by the application. 
        /// </summary> 
        /// <param name="path">The path of the used file.</param> 
        /// <exception cref="T:System.IO.FileNotFoundException"/> 
        /// <exception cref="T:System.InvalidOperationException">Attempt to notify of file usage was unsuccessful.</exception> 
        public FileLocker(string path) 
        { 
            try 
            { 
                path = Path.GetFullPath(path); 
            } 
            catch (Exception e) 
            { 
                throw new ArgumentException("The specified path is invalid.", "path", e); 
            } 
            if (!File.Exists(path)) 
            { 
                throw new FileNotFoundException("The specified file does not exist.", path); 
            } 
            IBindCtx ctx; 
            int ret = NativeMethods.CreateBindCtx(0, out ctx); 
            if (ret != 0 || ctx == null) 
            { 
                throw new InvalidOperationException(); 
            } 
 
            IRunningObjectTable rot; 
            try 
            { 
                ctx.GetRunningObjectTable(out rot); 
                if (rot == null) 
                { 
                    throw new InvalidOperationException(); 
                } 
                try 
                { 
                    IMoniker mon; 
                    ret = NativeMethods.CreateFileMoniker(path, out mon); 
                    if (ret != 0 || mon == null) 
                    { 
                        throw new InvalidOperationException(); 
                    } 
 
                    try 
                    { 
                        try 
                        { 
                            cookie = rot.Register(NativeMethods.ROTFLAGS_ALLOWANYCLIENT | NativeMethods.ROTFLAGS_REGISTRATIONKEEPSALIVE, this, mon); 
                        } 
                        catch (COMException) 
                        { 
                            cookie = rot.Register(NativeMethods.ROTFLAGS_REGISTRATIONKEEPSALIVE, this, mon); 
                        } 
                    } 
                    finally 
                    { 
                        Marshal.ReleaseComObject(mon); 
                    } 
                } 
                finally 
                { 
                    Marshal.ReleaseComObject(rot); 
                } 
            } 
            finally 
            { 
                Marshal.ReleaseComObject(ctx); 
            } 
        } 
 
        ~FileLocker() 
        { 
            Dispose(false); 
        } 
 
        private int cookie; 
 
        /// <summary> 
        /// Cancels the notification and disposes the object. 
        /// </summary> 
        public void Dispose() 
        { 
            Dispose(true); 
            GC.SuppressFinalize(this); 
        } 
 
        private void Dispose(bool disposing) 
        { 
            try 
            { 
                Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\ShellNoRoam\MUICache", true).DeleteValue(GetAssemblyLocation(), false); 
            } 
            catch { } 
            IBindCtx ctx; 
            int ret = NativeMethods.CreateBindCtx(0, out ctx); 
            if (ret != 0 || ctx == null) 
            { 
                return; 
            } 
 
            IRunningObjectTable rot; 
            try 
            { 
                ctx.GetRunningObjectTable(out rot); 
                if (rot == null) 
                { 
                    return; 
                } 
                try 
                { 
                    rot.Revoke(cookie); 
                } 
                catch { } 
                finally 
                { 
                    try 
                    { 
                        Marshal.ReleaseComObject(rot); 
                    } 
                    catch { } 
                } 
            } 
            catch { } 
            finally 
            { 
                try 
                { 
                    Marshal.ReleaseComObject(ctx); 
                } 
                catch { } 
            } 
        } 
 
        #endregion 
 
        #region " IOleObject Members " 
 
        int NativeMethods.IOleObject.SetClientSite(object pClientSite) 
        { 
            throw new NotImplementedException(); 
        } 
 
        object NativeMethods.IOleObject.GetClientSite() 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.SetHostNames(string szContainerApp, string szContainerObj) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.Close(int dwSaveOption) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.SetMoniker(int dwWhichMoniker, object pmk) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.GetMoniker(int dwAssign, int dwWhichMoniker, out object moniker) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.InitFromData(IDataObject pDataObject, int fCreation, int dwReserved) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.GetClipboardData(int dwReserved, out IDataObject data) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.DoVerb(int iVerb, IntPtr lpmsg, object pActiveSite, int lindex, IntPtr hwndParent, NativeMethods.COMRECT lprcPosRect) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.EnumVerbs(out object e) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.OleUpdate() 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.IsUpToDate() 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.GetUserClassID(ref Guid pClsid) 
        { 
            try 
            { 
                pClsid = _GetAssemblyGuid(); 
            } 
            catch { } 
            return 0; 
        } 
 
        int NativeMethods.IOleObject.GetUserType(int dwFormOfType, out string userType) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.SetExtent(int dwDrawAspect, NativeMethods.SIZE pSizel) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.GetExtent(int dwDrawAspect, NativeMethods.SIZE pSizel) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.Advise(IAdviseSink pAdvSink, out int cookie) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.Unadvise(int dwConnection) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.EnumAdvise(out IEnumSTATDATA e) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.GetMiscStatus(int dwAspect, out int misc) 
        { 
            throw new NotImplementedException(); 
        } 
 
        int NativeMethods.IOleObject.SetColorScheme(NativeMethods.tagLOGPALETTE pLogpal) 
        { 
            throw new NotImplementedException(); 
        } 
 
        #endregion 
    } 
 
    #region " NativeMethods class " 
 
    internal static class NativeMethods 
    { 
        public const int ROTFLAGS_REGISTRATIONKEEPSALIVE = 0x1; 
        public const int ROTFLAGS_ALLOWANYCLIENT = 0x2; 
        [DllImport("ole32.dll")] 
        public static extern int CreateFileMoniker([MarshalAs(UnmanagedType.LPWStr)] string lpszPathName, out IMoniker ppmk); 
        [DllImport("ole32.dll")] 
        public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); 
 
        [StructLayout(LayoutKind.Sequential)] 
        public class COMRECT 
        { 
            public int left; 
            public int top; 
            public int right; 
            public int bottom; 
        } 
 
        [StructLayout(LayoutKind.Sequential)] 
        public class SIZE 
        { 
            public int cx; 
            public int cy; 
        } 
 
        [StructLayout(LayoutKind.Sequential)] 
        public sealed class tagLOGPALETTE 
        { 
            [MarshalAs(UnmanagedType.U2)] 
            public ushort palVersion; 
            [MarshalAs(UnmanagedType.U2)] 
            public ushort palNumEntries; 
        } 
 
        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SecurityCritical(SecurityCriticalScope.Everything), Guid("00000112-0000-0000-C000-000000000046"), SuppressUnmanagedCodeSecurity] 
        public interface IOleObject 
        { 
            [PreserveSig] 
            int SetClientSite([In, MarshalAs(UnmanagedType.Interface)] object pClientSite); 
            object GetClientSite(); 
            [PreserveSig] 
            int SetHostNames([In, MarshalAs(UnmanagedType.LPWStr)] string szContainerApp, [In, MarshalAs(UnmanagedType.LPWStr)] string szContainerObj); 
            [PreserveSig] 
            int Close(int dwSaveOption); 
            [PreserveSig] 
            int SetMoniker([In, MarshalAs(UnmanagedType.U4)] int dwWhichMoniker, [In, MarshalAs(UnmanagedType.Interface)] object pmk); 
            [PreserveSig] 
            int GetMoniker([In, MarshalAs(UnmanagedType.U4)] int dwAssign, [In, MarshalAs(UnmanagedType.U4)] int dwWhichMoniker, [MarshalAs(UnmanagedType.Interface)] out object moniker); 
            [PreserveSig] 
            int InitFromData([In, MarshalAs(UnmanagedType.Interface)] IDataObject pDataObject, int fCreation, [In, MarshalAs(UnmanagedType.U4)] int dwReserved); 
            [PreserveSig] 
            int GetClipboardData([In, MarshalAs(UnmanagedType.U4)] int dwReserved, out IDataObject data); 
            [PreserveSig] 
            int DoVerb(int iVerb, [In] IntPtr lpmsg, [In, MarshalAs(UnmanagedType.Interface)] object pActiveSite, int lindex, IntPtr hwndParent, [In] NativeMethods.COMRECT lprcPosRect); 
            [PreserveSig] 
            int EnumVerbs(out object e); 
            [PreserveSig] 
            int OleUpdate(); 
            [PreserveSig] 
            int IsUpToDate(); 
            [PreserveSig] 
            int GetUserClassID([In, Out] ref Guid pClsid); 
            [PreserveSig] 
            int GetUserType([In, MarshalAs(UnmanagedType.U4)] int dwFormOfType, [MarshalAs(UnmanagedType.LPWStr)] out string userType); 
            [PreserveSig] 
            int SetExtent([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, [In] NativeMethods.SIZE pSizel); 
            [PreserveSig] 
            int GetExtent([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, [Out] NativeMethods.SIZE pSizel); 
            [PreserveSig] 
            int Advise(IAdviseSink pAdvSink, out int cookie); 
            [PreserveSig] 
            int Unadvise([In, MarshalAs(UnmanagedType.U4)] int dwConnection); 
            [PreserveSig] 
            int EnumAdvise(out IEnumSTATDATA e); 
            [PreserveSig] 
            int GetMiscStatus([In, MarshalAs(UnmanagedType.U4)] int dwAspect, out int misc); 
            [PreserveSig] 
            int SetColorScheme([In] NativeMethods.tagLOGPALETTE pLogpal); 
        } 
 
    } 
 
    #endregion 
}