Golang fsnotify在Windows上为同一文件发送多个事件

I am writing a simple golang script to monitor Downloads folder on Windows. The idea is that whenever a new file gets downloaded it will be sent to printer. This works mostly as expected. Here is the code:

package main

import (
    "log"
    "fmt"
    "github.com/howeyc/fsnotify"
    "os/exec"
)

func main() {
    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan bool)

    // Process events
    go func() {
        for {
            select {
            case ev := <-watcher.Event:
                log.Println("event:", ev)
                c := exec.Command("cmd", "/C", "RawFileToPrinter.exe", ev.Name)
                if err := c.Run(); err != nil {
                    fmt.Println("Error: ", err)
                }

            case err := <-watcher.Error:
                log.Println("error:", err)
            }
        }
    }()

    err = watcher.Watch("C:\\Users\\admin\\Downloads")
    if err != nil {
        log.Fatal(err)
    }

    // Hang so program doesn't exit
    <-done

    /* ... do stuff ... */
    watcher.Close()
}

Unfortunately I find that multiple events are sent for the same file as shown in the following log:

2019/02/11 15:34:26 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": CREATE
(*fsnotify.FileEvent)(0x10e821c0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": CREATE)
2019/02/11 15:34:37 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": MODIFY
(*fsnotify.FileEvent)(0x10e821d0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": MODIFY)
2019/02/11 15:34:40 event: "C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": RENAME
(*fsnotify.FileEvent)(0x10e821e0)("C:\\Users\\admin\\Downloads\\0fcc8a09-9c51-4c5e-a77c-d4f111f6931f.tmp": RENAME)
2019/02/11 15:34:41 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME
(*fsnotify.FileEvent)(0x10e821f0)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME)
2019/02/11 15:34:42 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME
(*fsnotify.FileEvent)(0x10e82200)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt.crdownload": RENAME)
2019/02/11 15:34:44 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": RENAME
(*fsnotify.FileEvent)(0x10e82210)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": RENAME)
2019/02/11 15:34:46 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82220)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)
2019/02/11 15:34:47 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82230)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)
2019/02/11 15:34:48 event: "C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY
(*fsnotify.FileEvent)(0x10e82240)("C:\\Users\\admin\\Downloads\\Generico-Bill-MULW-132482.txt": MODIFY)

This causes same file to be printed multiple times. The exe ignores *.tmp and *.crdownload. Is it possible to get a single event? If not how do I handle this condition?

First off: *fsnotify.FileEvent indicates you are using an old version of the fsnotify package, change your dependency to: github.com/fsnotify/fsnotify.

I don't have a Windows machine to test on, so I can't guarantee that this will fix your problem. But looks to me, that the later file modifications are attribute changes.

Watching only the renames to other than *.tmp and *.crdownload should be enough to print your files, since your RawFileToPrinter.exe shouldn't care that the file was being downloaded from the internet or whatever attributes are beeing set after finishing your download.