E-mail notification on file added to directory

I'm new to attempting to get Windows to send e-mail alerts.  I'm a web programmer by trade, so please send me directions as to what to do with the code and how to run it in order to make it work.

I need a notification sent out via email when a new file is added to a particular directory.  I would like for this process of checking for a new file to be run on an hourly basis if possible.  Please comment all code to explain the steps and where to modify to fit my needs.

Thank you for, "holding my hand" with the coding!
Who is Participating?

I wrote this code which works for me so hopefully you should be ok with it as well.

You will need to cut and paste the below code in to a new vbs file. I called it folder_monitor.vbs

You will need to change the following things:
change     strFolder = "c:\temp\watchme"   to the name of the folder that you want to monitor
change     oMessage.Sender = "server@mycompany.com" to the account you want the email to come from
change     oMessage.To = "admin@mycompany.com" to the account you want to send the email too
change     oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mycompany.com" to the name of your smtp server

You can find additional information about setting up the smtp here http://www.paulsadowski.com/WSH/cdo.htm

Once you have made these changes you can create a scheduled task to run the vbs file every hour.

The first time it is run it will create a text file called contents.txt in the same folder as the vbs file and it will populate this file wth the names of all of the files in the folder you specify.

On any subsequent execution it will compare the contents of the txt file to the current files in the directory and if there are any new ones it will add them to the string which will be sent in the email.

At the same time it updates the txt file with any new files for the next run.

If at any time the contents.txt file is removed then on the next execution it will be recreated.

Any problems, questions about the code etc let me know




  Dim oFSO
  Dim oFolder
  Dim oDic
  Dim strFolder
  Dim strContent


  Sub main()

    ' The filesystem object reference
    Set oFSO = CreateObject("Scripting.FileSystemObject")

    ' The name of the folder being watched
    strFolder = "c:\temp\watchme"  
    ' The location of the control text file
    strContent = oFSO.GetParentFolderName(wscript.ScriptFullName) & "\" & "contents.txt"

    ' Connect to the folder to be monitored
    Set oFolder = oFSo.GetFolder(strFolder)

    ' Create the dictionary object
    Set oDic = CreateObject("Scripting.Dictionary")

    ' If the text file does not exist then create it
    If Not oFSO.FileExists(strContent) Then
    End If

    ' Add each file from the text file to the dictionary

    ' Compare the contents of the text file to the current files
    strFiles = check_Folder

    ' If there were additional files send an email and update the text file for the next run
    If strFiles <> "" Then
    End If

    ' Tidy up
    Set oDic = Nothing    
    Set oFolder = Nothing
    Set oFSO = Nothing

  End Sub

  Private Sub Send_Email
    Set oMessage = CreateObject("CDO.Message")

    oMessage.Subject = "The following files have been added to the folder: " & strFolder
    oMessage.Sender = "server@mycompany.com"
    oMessage.To = "admin@mycompany.com"
    oMessage.TextBody = strFiles

    '==This section provides the configuration information for the remote SMTP server.
    '==Normally you will only change the server name or IP.

    oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2

    'Name or IP of Remote SMTP Server
    oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.mycompany.com"

    'Server port (typically 25)
    oMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25


    '==End remote SMTP server configuration section==


    Set oMessage = Nothing
  End Sub

  Private Function check_Folder()

    ' For each file in the folder
    For Each oFile In oFolder.Files
      ' If the file does not exist in the dictionary (ie a new file)
      If Not oDic.Exists(oFile.Name) Then
        ' Add the file name to the list of files
        strFiles = strFiles & oFile.Name & chr(10)
      End If

    ' Return the list of new files
    check_Folder = strFiles

  End Function

  Private Sub populate_Dictionary()

    ' Get the input file for reading
    Set oInput = oFSO.OpenTextFile(strContent,1)

    ' For each line in the file (ie each file)
    While Not oInput.AtEndOfStream
      ' Add the file name to the dictionary
      oDic.Add oInput.ReadLine(),"-"

    ' Tidy uo
    oInput.Close : Set oInput = Nothing

  End Sub

  Private Sub populate_TextFile()
    ' Open the file for writing
    Set oOutput = oFSO.OpenTextFile(strContent,2,True)

    ' For each file in the folder
    For Each oFile In oFolder.Files
      ' Add the file name to the file

    ' Tidy up
    oOutput.Close : Set oOutput = Nothing

  End Sub

  Here is a useful example from the documentation:

DWORD dwWaitStatus;
HANDLE dwChangeHandles[2];
// Watch the C:\WINDOWS directory for file creation and
// deletion.
dwChangeHandles[0] = FindFirstChangeNotification(
    "C:\\WINDOWS",                 // directory to watch
    FALSE,                         // do not watch the subtree
    FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes
if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
// Watch the C:\ subtree for directory creation and
// deletion.
dwChangeHandles[1] = FindFirstChangeNotification(
    "C:\\",                        // directory to watch
    TRUE,                          // watch the subtree
    FILE_NOTIFY_CHANGE_DIR_NAME);  // watch dir. name changes
if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
// Change notification is set. Now wait on both notification
// handles and refresh accordingly.
while (TRUE)
    // Wait for notification.
    dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
    switch (dwWaitStatus)
        case WAIT_OBJECT_0:
        // A file was created or deleted in C:\WINDOWS.
        // Refresh this directory and restart the
        // change notification. RefreshDirectory is an
        // application-defined function.
            if ( FindNextChangeNotification(
                    dwChangeHandles[0]) == FALSE )
        case WAIT_OBJECT_0 + 1:
        // A directory was created or deleted in C:\.
        // Refresh the directory tree and restart the
        // change notification. RefreshTree is an
        // application-defined function.
            if (FindNextChangeNotification(
                    dwChangeHandles[1]) == FALSE)

It'll be easier to do more explanations in parts in a separate post.

Hi will you be running this on a domain?

will there be an smtp server available for the email?

Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

johnson00Author Commented:
Corey -

Ok, I can follow the code, and it appears that it would work.  I just need to know what to do with it.  Do I save it as  a batch file and run in the background? How do I run it?
johnson00Author Commented:
This will be run on a server, and if it doesn't have an smtp server, I can set one up.

  I am not a big server developer, however you should be able to schedule this task in the task scheduler.  I don't know how fine of a time you will be able to specify in the GUI.  There is a Task Scheduler API that can be used to programmatically set triggers by the hour.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/taskschd/taskschd/task_scheduler_start_page.asp ["Platform SDK: Task Scheduler"]

  However, the idea is to always have this change detection and notification program running in the background or you will miss events between the hours you want to run the program.

  Now, what you could do in the same code sequence above is create a waitable timer, and check for that trigger in your WaitForMultipleObjects call.  The waitable timer is just another handle, and the time can be any specification you want.  When that timer triggers, use that as the point to send a queue of messages or notifications via email.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/waitable_timer_objects.asp ["Waitable Timer Objects"]

johnson00Author Commented:
I'm getting an error about connecting to the SMTP server.  

The transport failed to connect to the server line 73 char 5

Can I point it to an existing SMTP server?
oh absolutely yes, if you have an existing smtp server that you know to be working then that is even better as the only task then is getting this code to work with it rather than getting the smtp server to work

johnson00Author Commented:
Great!  I got it working now.  THANK YOU THANK YOU THANK YOU!!!!
heh good to hear, glad you got it going.

thanks for the grade

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.