読者です 読者をやめる 読者になる 読者になる

ぽにょろん

思いついたこととメモ

C#でファイルのウイルスチェックをする

C#

最近、ファイルのウイルスチェックをコードでやりたいといった会話をしたので、少し調べてみました。
結果、IAttachmentExecuteなるものを利用するとやりたいことが出来そうということが分かりました。

IAttachmentExecute interface (Windows)

必要な定義はAttachmentServicesとIAttachmentExecuteの二つ。

  • AttachmentServices
[ComImport, Guid("4125dd96-e03a-4103-8f70-e0597d803b9c"),ComVisible(false)]
public class AttachmentServices
{
}
  • IAttachmentExecute
[ComImport, Guid("73db1241-1e85-4581-8e4f-a81e1d0f8c57"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)]
public interface IAttachmentExecute
{
    int SetClientTitle(string pszTitle);
    void SetClientGuid(ref Guid guid);
    void SetLocalPath(string pszLocalPath);
    void SetFileName(string pszFileName);
    int SetSource(string pszSource);
    int SetReferrer(string pszReferrer);
    int CheckPolicy();
    int Prompt(IntPtr hwnd, ATTACHMENT_PROMPT prompt, out ATTACHMENT_ACTION paction);
    [PreserveSig]
    int Save();
    int Execute(IntPtr hwnd, string pszVerb, ref IntPtr phProcess);
    int SaveWithUI(IntPtr hwnd);
    int ClearClientState();
}
[ComVisible(false)]
public enum ATTACHMENT_PROMPT
{
    ATTACHMENT_PROMPT_NONE = 0x0000,
    ATTACHMENT_PROMPT_SAVE = 0x0001,
    ATTACHMENT_PROMPT_EXEC = 0x0002,
    ATTACHMENT_PROMPT_EXEC_OR_SAVE = 0x0003
}
[ComVisible(false)]
public enum ATTACHMENT_ACTION
{
    ATTACHMENT_ACTION_CANCEL = 0x0000,
    ATTACHMENT_ACTION_SAVE = 0x0001,
    ATTACHMENT_ACTION_EXEC = 0x0002
}

COM呼び出しになるので、アセンブリ情報のCOM参照可能にチェックが必要ですね。

あとは適当に、呼び出してあげれば良いです。

[STAThread]
static void Main(string[] args)
{
    var path = @"D:\Hoge.txt";
    var service = (IAttachmentExecute)new AttachmentServices();
    try
    {
        service.SetClientGuid(Guid.NewGuid());
        service.SetFileName(path);
        service.SetLocalPath(path);
        var result = service.Save();
        Console.WriteLine(result);
    }
    finally
    {
        service.ClearClientState();
        Marshal.ReleaseComObject(service);
    }
}

STAThreadからの呼び出しじゃないとエラーになるので注意です。(COMなので(笑)) Saveの戻り値をチェックしてあげれば結果が分かります。
Windows8.1 + Windows Defender の環境で eicar.com の検出と削除は確認しましたが、その他の環境はどうなのかやってません。

かなり勉強になりましたし、こんなこともできるんですねぇ。
ということで、作ってみました。

github.com

以下の2つは盛大に参考にさせていただきました。

devadjust.exblog.jp