RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 691071
Accepted
Александр Пузанов
Александр Пузанов
Asked:2020-07-12 02:32:34 +0000 UTC2020-07-12 02:32:34 +0000 UTC 2020-07-12 02:32:34 +0000 UTC

如何确定文件是否可用于打开和写入?

  • 772

网络上有一个文件夹,其中定期创建文件。需要将这些文件复制到另一个目录。您需要检查文件是否可用于复制,即 他不订阅吗?是否可以检查文件是否可写?例如,我通过Adobe Reader打开一个文件,这个文件应该不会被复制。我需要一个问题的答案,而不是“我如何知道一个文件是否被另一个程序打开进行修改?”

c#
  • 4 4 个回答
  • 10 Views

4 个回答

  • Voted
  1. sp7
    2020-07-12T15:01:34Z2020-07-12T15:01:34Z

    在我看来,了解一个文件是否被另一个进程占用的最清醒的方法是尝试复制它并System.IO.IOException在 I/O 错误的情况下获取它,如果没有访问它就会发生这种情况。尝试实现一种检查文件是否被锁定的方法不会给出特殊结果。由于没有人保证在调用锁检查方法和复制文件之间的间隔内,没有其他进程已经拿走了它。

    • 14
  2. Best Answer
    MSDN.WhiteKnight
    2020-10-06T01:20:48Z2020-10-06T01:20:48Z

    为此,您可以使用具有奇怪名称的库 Restart Manager。获取已占用文件的进程列表的示例 ( https://code.msdn.microsoft.com/windowsapps/How-to-know-the-process-704839f4 ):

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Text;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace RMTest
    {
        public partial class Form1 : Form
        {
            [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]
            public static extern UInt32 RmStartSession(out UInt32 pSessionHandle, UInt32 dwSessionFlags,
                string strSessionKey);
    
            [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]
            public static extern UInt32 RmRegisterResources(UInt32 dwSessionHandle,
            UInt32 nFiles,string[] rgsFilenames,UInt32 nApplications,
            UInt32 rgApplications,UInt32 nServices,UInt32 rgsServiceNames);
    
            [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]
            public static extern UInt32 RmGetList(UInt32 dwSessionHandle,  out UInt32 pnProcInfoNeeded,
            ref UInt32 pnProcInfo,[In, Out] RM_PROCESS_INFO[] rgAffectedApps,ref UInt32 lpdwRebootReasons);
    
            [DllImport("Rstrtmgr.dll", CharSet = CharSet.Unicode, PreserveSig = true, SetLastError = true, ExactSpelling = true)]
            public static extern UInt32  RmEndSession(UInt32 dwSessionHandle);
    
            const UInt32 RmRebootReasonNone = 0x0;
    
            /*Получение списка процессов, имеющих блокировку на файле*/
            static public List<Process> GetLockProcesses(string path)
            {
                uint handle;
                string key = Guid.NewGuid().ToString();
                List<Process> processes = new List<Process>();
                uint res = RmStartSession(out handle, (uint)0, key);
                if (res != 0)
                {
                    throw new Exception("Could not begin restart session. " +
                                        "Unable to determine file locker.");
                }
                try
                {
                    const int ERROR_MORE_DATA = 234;
                    uint pnProcInfoNeeded = 0, pnProcInfo = 0,
                        lpdwRebootReasons = RmRebootReasonNone;
                    string[] resources = new string[] { path };
                    res = RmRegisterResources(handle, (uint)resources.Length,
                                                resources, 0, 0, 0, 0);
                    if (res != 0)
                    {
                        throw new Exception("Could not register resource.");
                    }
    
                    res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null,
                                    ref lpdwRebootReasons);
                    if (res == ERROR_MORE_DATA)
                    {
                        // Create an array to store the process results. 
                        RM_PROCESS_INFO[] processInfo =
                            new RM_PROCESS_INFO[pnProcInfoNeeded];                    
                        pnProcInfo = pnProcInfoNeeded;
                        // Get the list. 
                        res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo,
                            processInfo, ref lpdwRebootReasons);
                        if (res == 0)
                        {
                            processes = new List<Process>((int)pnProcInfo);
                            // Enumerate all of the results and add them to the  
                            // list to be returned. 
                            for (int i = 0; i < pnProcInfo; i++)
                            {
                                try
                                {
                                    processes.Add(Process.GetProcessById(processInfo[i].
                                        Process.dwProcessId));
                                }
                                // Catch the error in case the process is no longer running. 
                                catch (ArgumentException) { }
                            }
                        }
                        else
                        {
                            throw new Exception("Could not list processes locking resource");
                        }
                    }
                    else if (res != 0)
                    {
                        throw new Exception("Could not list processes locking resource." +
                                            "Failed to get size of result.");
                    }
                }            
                finally
                {
                    RmEndSession(handle);
                }
                return processes;
            }
    
            public Form1()
            {
                InitializeComponent();
    
                string f = "C:\\some_file.pdf";
    
                var p = GetLockProcesses(f);
    
                textBox1.Text = "";
                foreach (Process proc in p)
                {
                    textBox1.Text += proc.ProcessName + Environment.NewLine;
                }
                ;
    
            }
        }
    
        [StructLayout(LayoutKind.Sequential)]
        public struct RM_UNIQUE_PROCESS
        {
            // The product identifier (PID). 
            public int dwProcessId;
            // The creation time of the process. 
            public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
        }
        /// <summary> 
        /// Describes an application that is to be registered with the Restart Manager. 
        /// </summary> 
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RM_PROCESS_INFO
        {
            const int CCH_RM_MAX_APP_NAME = 255;
            const int CCH_RM_MAX_SVC_NAME = 63;
    
            // Contains an RM_UNIQUE_PROCESS structure that uniquely identifies the 
            // application by its PID and the time the process began. 
            public RM_UNIQUE_PROCESS Process;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
            // If the process is a service, this parameter returns the  
            // long name for the service. 
            public string strAppName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
            // If the process is a service, this is the short name for the service. 
            public string strServiceShortName;
            // Contains an RM_APP_TYPE enumeration value. 
            public RM_APP_TYPE ApplicationType;
            // Contains a bit mask that describes the current status of the application. 
            public uint AppStatus;
            // Contains the Terminal Services session ID of the process. 
            public uint TSSessionId;
            // TRUE if the application can be restarted by the  
            // Restart Manager; otherwise, FALSE. 
            [MarshalAs(UnmanagedType.Bool)]
            public bool bRestartable;
        }
        /// <summary> 
        /// Specifies the type of application that is described by 
        /// the RM_PROCESS_INFO structure. 
        /// </summary> 
        public enum RM_APP_TYPE
        {
            // The application cannot be classified as any other type. 
            RmUnknownApp = 0,
            // A Windows application run as a stand-alone process that 
            // displays a top-level window. 
            RmMainWindow = 1,
            // A Windows application that does not run as a stand-alone 
            // process and does not display a top-level window. 
            RmOtherWindow = 2,
            // The application is a Windows service. 
            RmService = 3,
            // The application is Windows Explorer. 
            RmExplorer = 4,
            // The application is a stand-alone console application. 
            RmConsole = 5,
            // A system restart is required to complete the installation because 
            // a process cannot be shut down. 
            RmCritical = 1000
        } 
    
    }
    

    适用于从 Windows Vista 开始的操作系统。

    • 7
  3. Dmitriy
    2020-07-12T02:46:18Z2020-07-12T02:46:18Z

    这是完成的项目。 一切都通过位于的系统openfiles.exe完成c:\Windows\System32

    它支持许多操作,例如关闭文件、查询等。

    • 4
  4. bigov
    2020-10-11T10:12:37Z2020-10-11T10:12:37Z

    如果你想获得另一个文件夹中文件的高质量副本,那么你需要更改算法。您可能会在复制过程中丢失数据,您可以(理论上)在打开该文件的进程的同时请求文件的状态,如果该进程是本地进程,它将锁定您认为空闲的文件。

    在这个任务中正确的做法是简单地尝试一次复制所有内容,并在复制完成后检查结果。例如,按文件长度或复制前后修改文件的时间。未通过检查的文件被再次复制。好吧,更进一步 - 分析和处理出现的错误。

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5