Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.

Anyway to determine path being monitored with Win32::ChangeNotify?

by PhillyR (Acolyte)
on Nov 12, 2014 at 18:37 UTC ( [id://1107007]=perlquestion: print w/replies, xml ) Need Help??

PhillyR has asked for the wisdom of the Perl Monks concerning the following question:

I have some code that is monitoring changes to files within a directory. Everything is great.

 my $notify = Win32::ChangeNotify->new($dir, 0, 'FILE_NAME LAST_WRITE SIZE') or die "Unable to create notification for $dir\n";

If a user changes the name of monitored directory, the notifications still work. However, now the $dir value is out of sync with the actual directory name. Is there a way to get the name of the folder being monitored by $notify? I'm thinking something like $notify->path();

  • Comment on Anyway to determine path being monitored with Win32::ChangeNotify?
  • Download Code

Replies are listed 'Best First'.
Re: Any way to determine path being monitored with Win32::ChangeNotify?
by Athanasius (Archbishop) on Nov 13, 2014 at 03:16 UTC

    Hello PhillyR,

    With the ls utility from GnuWin tools you can use ls -i to get the inode of the monitored directory. If the user subsequently renames the directory, its inode number remains unchanged, allowing you to identify the directory and retrieve its new name.1 Here is some proof-of-concept code (minus error checking!):

    #! perl use strict; use warnings; my $dir = 'foo'; my $ls = (grep { /\s+$dir$/ } `ls -il`)[0]; $ls =~ /^\s*(\d+)/; my $inode = $1; print "$dir --> $inode "; rename $dir, 'bar'; $ls = (grep { /^\s*$inode\s+/ } `ls -il`)[0]; $ls =~ /:\d{2}\s+(.*)$/; print "--> $1\n";


    13:09 >perl foo --> 7318349394599033 --> bar 13:09 >

    (Tested on an NTFS file system under Windows 8.1, 64-bit.)

    Hope that helps,

    1See this discussion.

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      I'm really baffled by how your example works, as NTFS doesn't have inode numbers?

      (See the output from stat & lstat, where the inode number is always 0.)

      From what I can tell by looking at the ls.c (from the GnuWin project), it (same.c) uses the st_ino field returned by stat:

      #define SAME_INODE(Stat_buf_1, Stat_buf_2) \ ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \ && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev) static bool dev_ino_compare (void const *x, void const *y) { struct dev_ino const *a = x; struct dev_ino const *b = y; return SAME_INODE (*a, *b) ? true : false; }

      Which is (in my machine) always 0.

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        Hello i'm baffled too (but learned new word: baffled) because i knew inode was always 0 on windows.. but effectively the version suggested by Athanasius, ie gnuwin32 return some number while unxutils return 0.
        >touch test.txt > > >which ls.exe >C:\various_stuffs\bin\UnxUtils\usr\local\wbin\ls.exe > >ls -il test.txt 0 -rw-rw-rw- 1 user group 0 Nov 13 09:57 test.tx +t >C:\some_path\GnuWin32\bin\ls.exe -il test.txt >3377699722053632 -rw-rw-rw- 1 lt 0 0 2014-11-13 09:57 test.txt >

        Can someone tell us if we can use reliably this inode number?

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Anyway to determine path being monitored with Win32::ChangeNotify?
by GrandFather (Saint) on Nov 13, 2014 at 03:41 UTC

    Documentation for Windows API functions FindFirstChangeNotification and FindNextChangeNotification which are wrapped up by the module states:

    "these functions do not indicate the actual change"

    The documentation suggests ReadDirectoryChangesW be used to "retrieve information about the specific change". But that doesn't help your case unless you can monitor the parent directory instead, and I can't find a Perl module that wraps up ReadDirectoryChangesW in any case. You can probably call ReadDirectoryChangesW directly using Win32::API if that solves a problem for you.

    Perl is the programming world's equivalent of English
Re: Anyway to determine path being monitored with Win32::ChangeNotify?
by Anonymous Monk on Nov 13, 2014 at 07:46 UTC
Re: Anyway to determine path being monitored with Win32::ChangeNotify?
by james28909 (Deacon) on Nov 13, 2014 at 02:33 UTC
    my $dir = $ARGV[0]; my $notify = Win32::ChangeNotify->new($dir, 0, 'FILE_NAME LAST_WRITE S +IZE') or die "Unable to create notification for $dir\n";
    just run it as script name and the arg will be the dir you want to monitor. what is more interesting than this is getting the names of the files/dirs thats changed :)
      derp, completely missed the point of the user changing the name of the dir.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1107007]
Approved by atcroft
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (1)
As of 2024-04-25 00:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found