Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

E-mail notification on file added to directory

Posted on 2005-04-25
10
Medium Priority
?
306 Views
Last Modified: 2013-12-03
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!
0
Comment
Question by:johnson00
  • 4
  • 4
  • 2
10 Comments
 
LVL 8

Expert Comment

by:_corey_
ID: 13862901
johnson00,

  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)
    ExitProcess(GetLastError());
 
// 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)
    ExitProcess(GetLastError());
 
// Change notification is set. Now wait on both notification
// handles and refresh accordingly.
 
while (TRUE)
{
 
    // Wait for notification.
 
    dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
        FALSE, INFINITE);
 
    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.
 
            RefreshDirectory("C:\\WINDOWS")
            if ( FindNextChangeNotification(
                    dwChangeHandles[0]) == FALSE )
                ExitProcess(GetLastError());
            break;
 
        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.
 
            RefreshTree("C:\\");
            if (FindNextChangeNotification(
                    dwChangeHandles[1]) == FALSE)
                ExitProcess(GetLastError());
            break;
 
        default:
            ExitProcess(GetLastError());
    }
}

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

corey
0
 
LVL 15

Expert Comment

by:Colosseo
ID: 13862902
Hi will you be running this on a domain?

will there be an smtp server available for the email?

Scott
0
 
LVL 2

Author Comment

by:johnson00
ID: 13866279
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?
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
LVL 2

Author Comment

by:johnson00
ID: 13866289
This will be run on a server, and if it doesn't have an smtp server, I can set one up.
0
 
LVL 8

Expert Comment

by:_corey_
ID: 13867629
johnson00,

  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"]

corey
0
 
LVL 15

Accepted Solution

by:
Colosseo earned 2000 total points
ID: 13871581
Hi

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

Cheers

Scott

<<< CUT BELOW HERE >>>

  Dim oFSO
  Dim oFolder
  Dim oDic
  Dim strFolder
  Dim strContent

  main

  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
      populate_TextFile
    End If

    ' Add each file from the text file to the dictionary
    populate_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
      send_Email
      populate_TextFile
    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

    oMessage.Configuration.Fields.Update

    '==End remote SMTP server configuration section==

    oMessage.Send

    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
    Next

    ' 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(),"-"
    WEnd

    ' 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
      oOutput.WriteLine(oFile.Name)
    Next

    ' Tidy up
    oOutput.Close : Set oOutput = Nothing

  End Sub
0
 
LVL 2

Author Comment

by:johnson00
ID: 13872357
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?
0
 
LVL 15

Expert Comment

by:Colosseo
ID: 13873429
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

Scott
0
 
LVL 2

Author Comment

by:johnson00
ID: 13875419
Great!  I got it working now.  THANK YOU THANK YOU THANK YOU!!!!
0
 
LVL 15

Expert Comment

by:Colosseo
ID: 13876690
heh good to hear, glad you got it going.

thanks for the grade

Scott
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Is your data getting by on basic protection measures? In today’s climate of debilitating malware and ransomware—like WannaCry—that may not be enough. You need to establish more than basics, like a recovery plan that protects both data and endpoints.…

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question