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