Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 是否有可能合理地绕过扫描工作目录的防病毒程序?_Windows_Winapi_File_Error Handling_Filesystems - Fatal编程技术网

Windows 是否有可能合理地绕过扫描工作目录的防病毒程序?

Windows 是否有可能合理地绕过扫描工作目录的防病毒程序?,windows,winapi,file,error-handling,filesystems,Windows,Winapi,File,Error Handling,Filesystems,我的Win32应用程序在运行时会在指定的临时文件夹中执行大量磁盘操作,因此不可能对其进行认真的重新设计 有些客户端有防病毒软件,可以扫描同一个临时目录(它只是扫描所有内容)。我们试图说服他们禁用它-它不起作用,所以这也是不可能的 每隔一段时间(比如每一千个文件操作一次),我的应用程序都会尝试对一个文件执行操作,该文件当时被防病毒软件打开,因此被操作系统锁定。发生共享冲突并导致我的应用程序出错。这种情况平均每三分钟发生一次 在大多数典型情况下,临时文件夹最多可以包含100k个文件,因此我不喜欢让它

我的Win32应用程序在运行时会在指定的临时文件夹中执行大量磁盘操作,因此不可能对其进行认真的重新设计

有些客户端有防病毒软件,可以扫描同一个临时目录(它只是扫描所有内容)。我们试图说服他们禁用它-它不起作用,所以这也是不可能的

每隔一段时间(比如每一千个文件操作一次),我的应用程序都会尝试对一个文件执行操作,该文件当时被防病毒软件打开,因此被操作系统锁定。发生共享冲突并导致我的应用程序出错。这种情况平均每三分钟发生一次

在大多数典型情况下,临时文件夹最多可以包含100k个文件,因此我不喜欢让它们一直打开的想法,因为这可能会导致在某些边缘条件下耗尽资源

当需要的文件被锁定时,我的应用程序是否有一些合理的策略来应对这种情况?也许是这样的

for( int i = 0; i < ReasonableNumber; i++ ) {
    try {
        performOperation(); // do useful stuff here
        break;
    } catch( ... ) {
        if( i == ReasonableNumber - 1 ) {
            throw; //not to hide errors if unlock never happens
        }
    }
    Sleep( ReasonableInterval );
 }
for(int i=0;i

这是一个可行的策略吗?如果是,我的应用程序应该重试多少次,多久重试一次?如果有的话,有什么更好的主意吗?

能否更改应用程序,使其不释放文件句柄?如果您自己持有文件的锁,抗病毒应用程序将无法扫描它


否则,像你这样的策略会有所帮助,因为它只会降低概率,但不能解决问题。

棘手的问题。我的大多数想法都指向了你不想要的方向(例如重新设计)

我不知道您的目录中有多少文件,但如果没有那么多,您可以在程序运行时保持所有文件打开并锁定,从而解决问题


这样,病毒扫描程序将不再有机会中断您的文件访问。

如果有其他进程(无论是防病毒软件、备份实用程序,甚至是用户自己)可能会打开文件,那么您必须对这种可能性进行编码

您的解决方案,虽然可能不是最优雅的,但只要
reasonalNumber
足够大,肯定会起作用-在过去,我使用10作为合理的数字。我当然不会再高了,你可以用一个更低的值,比如5

睡眠的价值?最多100毫秒或200毫秒


请记住,应用程序在大多数情况下都会第一次获取文件。

在扫描文件时锁定文件的virusscanner非常糟糕。拥有如此糟糕病毒的客户需要更换他们的大脑…;-)

好了,别再唠叨了。如果某个文件被其他进程锁定,则可以使用建议的“重试”策略。OTOH,你真的需要关闭然后重新打开那些文件吗?在你的过程完成之前,你不能让它们打开吗? 提示:当您再次尝试重新打开文件时,请添加延迟(睡眠)。大约100毫秒就足够了。如果virusscanner将文件打开那么长时间,那么它将是一个非常糟糕的扫描仪。扫描程序如此糟糕的客户端应该看到异常消息。 通常,最多可尝试三次…->打开,失败时重试,第二次失败时重试,第三次失败时崩溃


记住以用户友好的方式崩溃。

取决于文件的大小,但对于10秒到100秒的Kb,我发现用100毫秒(0.1秒)进行5次尝试就足够了。如果您仍然偶尔遇到错误,请加倍等待,但是

如果您在代码中有一些地方需要这样做,我是否可以建议您采用功能性方法:

using System;

namespace Retry
{
    class Program
    {
        static void Main(string[] args)
        {
            int i = 0;
            Utils.Retry(() =>
            {
                i = i + 1;
                if (i < 3)
                    throw new ArgumentOutOfRangeException();
            });
            Console.WriteLine(i);
            Console.Write("Press any key...");
            Console.ReadKey();
        }
    }

    class Utils
    {
        public delegate void Retryable();
        static int RETRIES = 5;
        static int WAIT = 100; /*ms*/
        static public void Retry( Retryable retryable )
        {
            int retrys = RETRIES;
            int wait = WAIT;
            Exception err;
            do
            {
                try
                {
                    err = null;
                    retryable();
                }
                catch (Exception e)
                {
                    err = e;
                    if (retrys != 1)
                    {
                        System.Threading.Thread.Sleep(wait);
                        wait *= 2;
                    }
                }
            } while( --retrys > 0 && err != null );
            if (err != null)
                throw err;
        }
    }
}
使用系统;
命名空间重试
{
班级计划
{
静态void Main(字符串[]参数)
{
int i=0;
Utils.Retry(()=>
{
i=i+1;
如果(i<3)
抛出新ArgumentOutOfRangeException();
});
控制台写入线(i);
控制台。写入(“按任意键…”);
Console.ReadKey();
}
}
类Utils
{
公共委托void Retryable();
静态int重试次数=5次;
静态整数等待=100;/*ms*/
静态公共无效重试(可重试可重试)
{
int retrys=重试次数;
int wait=等待;
异常错误;
做
{
尝试
{
err=null;
retryable();
}
捕获(例外e)
{
err=e;
如果(retrys!=1)
{
系统。线程。线程。睡眠(等待);
等待*=2;
}
}
}而(--retrys>0&&err!=null);
if(err!=null)
犯错误;
}
}
}

我曾经使用过赛门铁克和AVG的防病毒软件,这些软件导致文件无法打开

我们在2002年赛门铁克公司遇到的一个常见问题是MSDev6,当时文件按以下顺序更新:

  • 打开一个文件
  • 内容在内存中修改
  • 应用程序需要提交更改
  • 应用程序使用文件的新副本+更改创建新的tmp文件
  • 应用程序删除旧文件
  • 应用程序将tmp文件复制到旧文件名
  • 应用程序删除tmp文件
  • 问题将是o