Class: Win32::DirMonitor
- Inherits:
-
Object
- Object
- Win32::DirMonitor
- Defined in:
- lib/win32/dirmonitor.rb
Defined Under Namespace
Classes: DirMonitorStruct, Error
Constant Summary collapse
- VERSION =
The version of the win32-dirmonitor library
'1.0.0'
Instance Attribute Summary collapse
-
#host ⇒ Object
readonly
The host on which to monitor the path.
-
#path ⇒ Object
readonly
The path to be monitored.
Instance Method Summary collapse
-
#initialize(path, host = Socket.gethostname) ⇒ DirMonitor
constructor
Creates a new DirMonitor object which sets the path and hostname on which the filesystem will be monitored for changes.
-
#wait(seconds = nil) ⇒ Object
A event loop that will yield a DirMonitorStruct object whenever there is a change in a file on the path set in the constructor.
Constructor Details
#initialize(path, host = Socket.gethostname) ⇒ DirMonitor
Creates a new DirMonitor object which sets the path and hostname on which the filesystem will be monitored for changes. If no hostname is provided, then the current host is assumed.
30 31 32 33 34 35 36 37 38 |
# File 'lib/win32/dirmonitor.rb', line 30 def initialize(path, host = Socket.gethostname) raise ArgumentError unless File.exists?(path) raise TypeError unless path.is_a?(String) raise TypeError unless host.is_a?(String) @path = path.tr("/", "\\") @host = host @conn = "winmgmts:{impersonationlevel=impersonate}!//#{host}/root/cimv2" end |
Instance Attribute Details
#host ⇒ Object (readonly)
The host on which to monitor the path.
24 25 26 |
# File 'lib/win32/dirmonitor.rb', line 24 def host @host end |
#path ⇒ Object (readonly)
The path to be monitored.
21 22 23 |
# File 'lib/win32/dirmonitor.rb', line 21 def path @path end |
Instance Method Details
#wait(seconds = nil) ⇒ Object
A event loop that will yield a DirMonitorStruct object whenever there is a change in a file on the path set in the constructor. The loop will timeout after the number of seconds provided, or indefinitely if no argument is provided.
The DirMonitorStruct contains the following members:
-
file # The full path of the file that was changed.
-
action # Either create, delete or modify.
-
changes # If modified, includes an array of changes.
If a modification occurs, the ‘changes’ struct member contains an array of arrays that describes the change. Each sub-array contains three members - the item that was modified, the previous value, and the current value.
Example:
mon = Win32::DirMonitor.new(“C:/Users/foo”)
# Monitor filesystem for one minute. mon.wait(60){ |s| p s }
# Sample struct returned after file was marked # hidden and read-only:
#<struct Struct::DirMonitorStruct
file="c:\\Users\\foo\\test.txt",
action="modify",
changes=[
["AccessMask", "2032127", "2032057"],
["Hidden", "false", "true"],
["Writeable", "true", "false"]
]
>
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/win32/dirmonitor.rb', line 76 def wait(seconds = nil) raise TypeError unless seconds.is_a?(Numeric) if seconds ole = WIN32OLE.connect(@conn) drive = @path.split(':').first + ":" folder = @path.split(':').last.gsub("\\", "\\\\\\\\") folder << "\\\\" unless folder[-1] == "\\" query = %Q{ select * from __instanceOperationEvent within 2 where targetInstance isa 'CIM_DataFile' and targetInstance.Drive='#{drive}' and targetInstance.Path='#{folder}' } # Asynchronous call. This will let the user break out of it manually. sink = WIN32OLE.new('WbemScripting.SWbemSink') event = WIN32OLE_EVENT.new(sink) ole.execNotificationQueryAsync(sink, query) sleep 0.5 event.on_event("OnObjectReady"){ |object, context| target = object.TargetInstance struct = DirMonitorStruct.new struct[:file] = target.Name case object.Path_.Class.to_s when "__InstanceCreationEvent" struct[:action] = 'create' when "__InstanceDeletionEvent" struct[:action] = 'delete' when "__InstanceModificationEvent" previous = object.PreviousInstance struct[:action] = 'modify' struct[:changes] = [] target.Properties_.each{ |prop| if prop.Value != previous.send(prop.Name) struct[:changes] << [ prop.Name, previous.send(prop.Name).to_s, prop.Value.to_s ] end } end yield struct } # If an argument is provided, timeout after that many seconds. if seconds begin Timeout.timeout(seconds){ loop do WIN32OLE_EVENT. end } rescue Timeout::Error # Do nothing, return control to user end else loop do WIN32OLE_EVENT. end end end |