ShellNotify Class

Properties   Methods   Events   Config Settings   Errors  

The ShellNotify class enables monitoring file system change notifications.

Syntax

class cbfsshell.ShellNotify

Remarks

The ShellNotify class provides a simple way to monitor changes such as creation, renaming, deletion, or modification of files or folders. The class uses the Windows API to register as an observer of shell notifications.

Activate

First, set the path property to the desired location to listen for changes. The target may be a local or remote filesystem, and a path may be specified using the drive letter format or a UNC path. For instance, you can set C:\Path\To\Folder if the target is a mapped drive, or \\servername\sharename if the target is a network share.

After that, you may set the recursive property depending on whether you would like to include changes for subfolders. You may also set the value of notifications to control the types of changes to monitor.

ShellNotify component = new ShellNotify(); component.Path = "C:\Temp"; component.Recursive = True;

The next step is to call activate to begin listening for changes. As users interact with files and folders at the specified Path, the corresponding events will be triggered. Activate must be called again if the Explorer process is terminated.

component.Activate();

Deactivate

To unregister as an observer of changes, call the deactivate method. This action will cease monitoring change notifications and only needs to be called once.

component.Deactivate();

PIDLs

A PIDL (or an IDL) is a fundamental Windows Shell concept. At a high level, it is pretty simple, as it is just a value that represents a Windows Shell item in the Windows Shell Namespace. It is a bit like a full filesystem path for a physical file or folder, except that it is a binary object and not a string. The name "PIDL" and "IDL" can be used interchangeably. The leading P stands for pointer, the IDL stands for item identifier list, and PIDL generally refers to an IDL itself rather than the pointer to it.

The below information is provided as a general knowledge. Your application will deal with PIDLs only when they denote some Windows Shell items that are not necessarily a part of the Windows Shell namespace extension that you create. Such PIDLs can be used with the Windows Shell API if you decide to call it directly. When CBFS Shell exposes these PIDL values they will appear hex-encoded. If an application needs to call a shell function, it has to decode the PIDL before calling that function.

Just like a full filesystem path is a list of strings separated by the directory separator (on Windows, it is the \ (backslash) character), a PIDL is a list (L is for list) of Ids (identifiers). Unlike a filesystem path, though, a PIDL is binary, and Ids are separated by a special PIDL separator (two consecutive zero bytes).

Microsoft provides more details about PIDLs here Identifying Namespace Objects.

Troubleshooting

Following are some helpful resources for troubleshooting issues.

  • If events are not triggered for any changes, note that the class relies on Explorer running and not terminating or restarting. If the Explorer process ends then you will need to call activate again.
  • If certain events are not triggered, it may be that the system components behave differently depending on the target you are monitoring. For instance, to monitor changes to a network share one needs to handle on_item_changed.
  • If you are seeing strange behavior not contained in this list, please reach out to us with a description of the problem and we are happy to help. Our support team is available over email at support@callback.com

Property List


The following is the full list of the properties of the class with short descriptions. Click on the links for further details.

notificationsThe property specifies which changes to monitor.
pathThe property specifies what path or namespace item to monitor.
recursiveThis property specifies whether changes in subfolders should be monitored.

Method List


The following is the full list of the methods of the class with short descriptions. Click on the links for further details.

activateThis method initiates monitoring for changes.
configSets or retrieves a configuration setting.
deactivateThis method stops monitoring changes.

Event List


The following is the full list of the events fired by the class with short descriptions. Click on the links for further details.

on_errorThis event is fired if an unhandled error occurs during an event.
on_file_createdThis event fires when a file is created.
on_file_deletedThis event fires when a file is deleted.
on_file_renamedThis event fires when a file is renamed.
on_folder_createdThis event fires when a folder is created.
on_folder_deletedThis event fires when a folder is deleted.
on_folder_renamedThis event fires when a folder is renamed.
on_item_changedThis event fires when any item is changed.

Config Settings


The following is a list of config settings for the class with short descriptions. Click on the links for further details.

BuildInfoInformation about the product's build.
LicenseInfoInformation about the current license.

notifications Property

The property specifies which changes to monitor.

Syntax

def get_notifications() -> int: ...
def set_notifications(value: int) -> None: ...

notifications = property(get_notifications, set_notifications)

Default Value

0x0002001F

Remarks

The property specifies which changes the class should monitor. The value may be a combination of the following flags:

UPDATE_TYPE_CREATE0x00000001A new item or folder is created.

This flag must be exclusive if used.

UPDATE_TYPE_CHANGE0x00000002An item or folder has been changed.

For folders, use this flag to tell the Windows Shell that the folder's contents have been changed.

UPDATE_TYPE_DELETE0x00000004An item or folder has been deleted.

UPDATE_TYPE_ATTRIBUTES0x00000008The attributes of an item or a folder have been updated.

UPDATE_TYPE_RENAME0x00000010An item was renamed; its name and possibly its Id have been changed.

This flag must be exclusive if used.

The default value of 0x0002001F (CHANGE_NOTIFY_DEFAULT) is a combination of the following flags:

path Property

The property specifies what path or namespace item to monitor.

Syntax

def get_path() -> str: ...
def set_path(value: str) -> None: ...

path = property(get_path, set_path)

Default Value

""

Remarks

This property specifies the target to monitor. If omitted, all of the Windows Shell namespace is monitored. A target may be any namespace item such as a folder or non-folder item.

An application may set this property to a filesystem path in drive-letter format, a path in UNC format, or a hex-encoded PIDL if a Windows Shell folder or item with no filesystem path is to be monitored. For instance:

  • C:\Path\To\Folder
  • \\<server>\<share>

recursive Property

This property specifies whether changes in subfolders should be monitored.

Syntax

def get_recursive() -> bool: ...
def set_recursive(value: bool) -> None: ...

recursive = property(get_recursive, set_recursive)

Default Value

TRUE

Remarks

This property specifies whether changes in subfolders of the folder specified by path property should also be monitored. This setting will be ignored if the path property references a non-folder item.

activate Method

This method initiates monitoring for changes.

Syntax

def activate() -> None: ...

Remarks

Use this method to begin monitoring for changes in the target location specified by the path property. The types of changes that will be included in monitoring are set in the notifications property.

Activate must be called again if the Explorer process is terminated.

config Method

Sets or retrieves a configuration setting.

Syntax

def config(configuration_string: str) -> str: ...

Remarks

config is a generic method available in every class. It is used to set and retrieve configuration settings for the class.

These settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these internal properties is provided through the config method.

To set a configuration setting named PROPERTY, you must call Config("PROPERTY=VALUE"), where VALUE is the value of the setting expressed as a string. For boolean values, use the strings "True", "False", "0", "1", "Yes", or "No" (case does not matter).

To read (query) the value of a configuration setting, you must call Config("PROPERTY"). The value will be returned as a string.

deactivate Method

This method stops monitoring changes.

Syntax

def deactivate() -> None: ...

Remarks

Use this method to stop monitoring for changes and unregister as an observer of change notifications.

on_error Event

This event is fired if an unhandled error occurs during an event.

Syntax

class ShellNotifyErrorEventParams(object):
  @property
  def error_code() -> int: ...

  @property
  def description() -> str: ...

# In class ShellNotify:
@property
def on_error() -> Callable[[ShellNotifyErrorEventParams], None]: ...
@on_error.setter
def on_error(event_hook: Callable[[ShellNotifyErrorEventParams], None]) -> None: ...

Remarks

This event fires if an unhandled error occurs. Developers can use this information to track down unhandled errors that occur in the class.

ErrorCode contains an error code and Description contains a textual description of the error.

on_file_created Event

This event fires when a file is created.

Syntax

class ShellNotifyFileCreatedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

# In class ShellNotify:
@property
def on_file_created() -> Callable[[ShellNotifyFileCreatedEventParams], None]: ...
@on_file_created.setter
def on_file_created(event_hook: Callable[[ShellNotifyFileCreatedEventParams], None]) -> None: ...

Remarks

This event fires upon creation, when the Windows Shell registers file creation within the namespace.

PIDL contains a byte array that represents an item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_file_deleted Event

This event fires when a file is deleted.

Syntax

class ShellNotifyFileDeletedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

# In class ShellNotify:
@property
def on_file_deleted() -> Callable[[ShellNotifyFileDeletedEventParams], None]: ...
@on_file_deleted.setter
def on_file_deleted(event_hook: Callable[[ShellNotifyFileDeletedEventParams], None]) -> None: ...

Remarks

This event fires upon deletion, when the Windows Shell has registered file deletion.

PIDL contains a byte array that represents an item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_file_renamed Event

This event fires when a file is renamed.

Syntax

class ShellNotifyFileRenamedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

  @property
  def new_pidl() -> bytes: ...

  @property
  def new_path() -> str: ...

# In class ShellNotify:
@property
def on_file_renamed() -> Callable[[ShellNotifyFileRenamedEventParams], None]: ...
@on_file_renamed.setter
def on_file_renamed(event_hook: Callable[[ShellNotifyFileRenamedEventParams], None]) -> None: ...

Remarks

This event fires upon renaming, when the Windows Shell has registered file renaming in one or more Windows Shell items.

PIDL contains a byte array that represents an previous item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full previous path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

NewPIDL contains the new PIDL.

NewPath contains the new path. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_folder_created Event

This event fires when a folder is created.

Syntax

class ShellNotifyFolderCreatedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

# In class ShellNotify:
@property
def on_folder_created() -> Callable[[ShellNotifyFolderCreatedEventParams], None]: ...
@on_folder_created.setter
def on_folder_created(event_hook: Callable[[ShellNotifyFolderCreatedEventParams], None]) -> None: ...

Remarks

This event fires upon folder creation, when the Windows Shell has registered a folder is created.

PIDL contains a byte array that represents an item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_folder_deleted Event

This event fires when a folder is deleted.

Syntax

class ShellNotifyFolderDeletedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

# In class ShellNotify:
@property
def on_folder_deleted() -> Callable[[ShellNotifyFolderDeletedEventParams], None]: ...
@on_folder_deleted.setter
def on_folder_deleted(event_hook: Callable[[ShellNotifyFolderDeletedEventParams], None]) -> None: ...

Remarks

This event fires upon folder deletion, when the Windows Shell has registered a folder has been deleted.

PIDL contains a byte array that represents an item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_folder_renamed Event

This event fires when a folder is renamed.

Syntax

class ShellNotifyFolderRenamedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

  @property
  def new_pidl() -> bytes: ...

  @property
  def new_path() -> str: ...

# In class ShellNotify:
@property
def on_folder_renamed() -> Callable[[ShellNotifyFolderRenamedEventParams], None]: ...
@on_folder_renamed.setter
def on_folder_renamed(event_hook: Callable[[ShellNotifyFolderRenamedEventParams], None]) -> None: ...

Remarks

This event fires upon folder renaming, when the Windows Shell has registered renaming in one or more Windows Shell items.

PIDL contains a byte array that represents an previous item in the Windows Shell namespace. Please see PIDL for more information.

Path contains the full previous path of the item. This parameter is only applicable when the item is part of a filesystem with a path.

NewPIDL contains a new PIDL.

NewPath contains a new path. This parameter is only applicable when the item is part of a filesystem with a path.

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

on_item_changed Event

This event fires when any item is changed.

Syntax

class ShellNotifyItemChangedEventParams(object):
  @property
  def pidl() -> bytes: ...

  @property
  def path() -> str: ...

  @property
  def new_pidl() -> bytes: ...

  @property
  def new_path() -> str: ...

  @property
  def changes() -> int: ...

# In class ShellNotify:
@property
def on_item_changed() -> Callable[[ShellNotifyItemChangedEventParams], None]: ...
@on_item_changed.setter
def on_item_changed(event_hook: Callable[[ShellNotifyItemChangedEventParams], None]) -> None: ...

Remarks

This event fires upon any change, when the Windows Shell has registered a creation, deletion, renaming, or updates in one or more Windows Shell items. The types of updates can include changes to size, attributes, security settings, last write, and last access time.

PIDL contains a byte array that represents an item in the Windows Shell namespace. If the set of changes includes renaming, this parameter contains the previous PIDL. Please see PIDL for more information.

Path contains the full path of the item. This parameter is only applicable when the item is part of a filesystem with a path. If the set of changes includes renaming, this parameter contains the previous Path.

NewPIDL contains a new PIDL. This parameter is only used when the set of changes includes renaming.

NewPath contains a new path. This parameter is only used when the set of changes includes renaming.

Changes specifies the type of change. The value can be one of the following:

CHANGE_NOTIFY_RENAME0x00000001The name of a nonfolder item has changed.

Both PIDL/Path and NewPIDL/NewPath parameters are valid. Renaming of a folder is indicated by the CHANGE_NOTIFY_RENAME_FOLDER flag.

CHANGE_NOTIFY_CREATE0x00000002A nonfolder item has been created.

Either PIDL, Path, or both parameters are valid. Creation of a folder is indicated by the CHANGE_NOTIFY_CREATE_FOLDER flag.

CHANGE_NOTIFY_DELETE0x00000004A nonfolder item has been deleted.

Either PIDL, Path, or both parameters are valid. Deletion of a folder is indicated by the CHANGE_NOTIFY_DELETE_FOLDER flag.

CHANGE_NOTIFY_CREATE_FOLDER0x00000008A folder has been created.

Either PIDL, Path, or both parameters are valid.

CHANGE_NOTIFY_DELETE_FOLDER0x00000010A folder has been removed.

Either PIDL, Path, or both parameters are valid.

CHANGE_NOTIFY_ATTRIBUTES0x00000800The attributes of an item or folder have changed

Either PIDL, Path, or both parameters are valid.

CHANGE_NOTIFY_UPDATE_FOLDER0x00001000The contents of an existing folder have changed, but the folder still exists and has not been renamed.

Either PIDL, Path, or both parameters are valid.

CHANGE_NOTIFY_UPDATE0x00002000An existing item (a folder or a non-folder item) has changed, but the item still exists and has not been renamed.

Either PIDL, Path, or both parameters are valid.

CHANGE_NOTIFY_RENAME_FOLDER0x00020000The name of a folder has changed.

Both PIDL/Path and NewPIDL/NewPath parameters are valid.

CHANGE_NOTIFY_DEFAULT0x0002001FThe default value of the Notifications property

Note: The events are triggered in the same thread that the Windows Shell used for a notification. Performing time-consuming operations within this event will prevent other events firing in a timely manner and may affect overall performance.

ShellNotify Config Settings

The class accepts one or more of the following configuration settings. Configuration settings are similar in functionality to properties, but they are rarely used. In order to avoid "polluting" the property namespace of the class, access to these internal properties is provided through the config method.

Base Config Settings

BuildInfo:   Information about the product's build.

When queried, this setting will return a string containing information about the product's build.

LicenseInfo:   Information about the current license.

When queried, this setting will return a string containing information about the license this instance of a class is using. It will return the following information:

  • Product: The product the license is for.
  • Product Key: The key the license was generated from.
  • License Source: Where the license was found (e.g., RuntimeLicense, License File).
  • License Type: The type of license installed (e.g., Royalty Free, Single Server).

ShellNotify Errors

ShellNotify Errors

2    An item with given ID cannot be found. The CBFSSHELL_ERR_FILE_NOT_FOUND constant is provided for convenience and may be used in place of the numeric value.
20    Cannot load native proxy DLL. The CBFSSHELL_ERR_CANT_LOAD_PROXY constant is provided for convenience and may be used in place of the numeric value.
28    The major version of the proxy DLL doesn't match the major version of the .NET assembly. The CBFSSHELL_ERR_PROXY_VERSION_MISMATCH constant is provided for convenience and may be used in place of the numeric value.
38    End of data stream has been reached and no data could be read. The CBFSSHELL_ERR_STREAM_EOF constant is provided for convenience and may be used in place of the numeric value.
55    Proxy DLL not installed properly. The CBFSSHELL_ERR_NOT_INSTALLED constant is provided for convenience and may be used in place of the numeric value.
56    Installation of the native proxy DLL failed. The CBFSSHELL_ERR_INSTALL_FAILED constant is provided for convenience and may be used in place of the numeric value.
57    Uninstallation of the native proxy DLL failed. The CBFSSHELL_ERR_UNINSTALL_FAILED constant is provided for convenience and may be used in place of the numeric value.
58    Initialization of the native proxy DLL failed. The CBFSSHELL_ERR_INIT_FAILED constant is provided for convenience and may be used in place of the numeric value.
59    The current license and the ID in the native proxy DLL name don't match. The CBFSSHELL_ERR_PROXY_NAME_MISMATCH constant is provided for convenience and may be used in place of the numeric value.
60    Writing to the Windows registry failed. The CBFSSHELL_ERR_CANT_WRITE_TO_REGISTRY constant is provided for convenience and may be used in place of the numeric value.
61    This Menu instance has already been started. The CBFSSHELL_ERR_ALREADY_STARTED constant is provided for convenience and may be used in place of the numeric value.
62    A menu item with the same verb is already registered. The CBFSSHELL_ERR_MENU_ITEM_ALREADY_REG constant is provided for convenience and may be used in place of the numeric value.
63    No menu items have been registered. The CBFSSHELL_ERR_MENU_ITEM_NOT_REG constant is provided for convenience and may be used in place of the numeric value.
87    The passed parameter was not valid. The CBFSSHELL_ERR_INVALID_PARAMETER constant is provided for convenience and may be used in place of the numeric value.
122    The provided buffer is too small to accommodate all the data that must be placed in it. The CBFSSHELL_ERR_INSUFFICIENT_BUFFER constant is provided for convenience and may be used in place of the numeric value.