From 6bb487fe3a33f62d90f6e9d8db85aadfe00a303e Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Tue, 30 Aug 2016 10:26:33 -0500 Subject: [PATCH] Use `dir` command on Windows for checking mount points If you call `os.path.exists` on a removable drive that is currently in the "ejected" state (which often happens when flashing multiple devices at the same time), then an error dialog will be shown that blocks the python process until the user interacts with it. You can globally disable these error boxes, but this is undesirable as it may mask other errors that occur. Windows has APIs that allow it to check if a device is ready before accessing the file system, however this is hard to access from Python. Instead, we use the `dir` command, which will error but not cause a blocking error dialog. For other OSes, we just use `os.path.exists`. --- mbed_lstools/lstools_base.py | 13 +++++++++++++ mbed_lstools/lstools_win7.py | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/mbed_lstools/lstools_base.py b/mbed_lstools/lstools_base.py index 72264f3..45d8ab6 100644 --- a/mbed_lstools/lstools_base.py +++ b/mbed_lstools/lstools_base.py @@ -720,6 +720,19 @@ def scan_html_line_for_target_id(self, line): return result return None + def mount_point_ready(self, path): + """! Check if a mount point is ready for file operations + @return Returns True if the given path exists, False otherwise + """ + result = os.path.exists(path) + + if result: + self.debug(self.mount_point_ready.__name__, "Mount point %s is ready" % path) + else: + self.debug(self.mount_point_ready.__name__, "Mount point %s does not exist" % (path)) + + return result + @staticmethod def run_cli_process(cmd, shell=True): """! Runs command as a process and return stdout, stderr and ret code diff --git a/mbed_lstools/lstools_win7.py b/mbed_lstools/lstools_win7.py index 10024d5..c5de723 100644 --- a/mbed_lstools/lstools_win7.py +++ b/mbed_lstools/lstools_win7.py @@ -132,7 +132,7 @@ def get_connected_mbeds(self): @return Returns [(, ), ..] @details Helper function """ - return [m for m in self.get_mbeds() if os.path.exists(m[0])] + return [m for m in self.get_mbeds() if self.mount_point_ready(m[0])] def get_mbeds(self): """! Function filters devices' mount points for valid TargetID @@ -198,3 +198,22 @@ def regbin2str(self, regbin): """! Decode registry binary to readable string """ return filter(lambda ch: ch in string.printable, regbin) + + def mount_point_ready(self, path): + """! Check if a mount point is ready for file operations + @return Returns True if the given path exists, False otherwise + @details Calling the Windows command `dir` instead of using the python + `os.path.exists`. The latter causes a Python error box to appear claiming + there is "No Disk" for some devices that are in the ejected state. Calling + `dir` prevents this since it uses the Windows API to determine if the + device is ready before accessing the file system. + """ + stdout, stderr, retcode = self.run_cli_process('dir %s' % path) + result = True if retcode == 0 else False + + if result: + self.debug(self.mount_point_ready.__name__, "Mount point %s is ready" % path) + else: + self.debug(self.mount_point_ready.__name__, "Mount point %s reported not ready with error '%s'" % (path, stderr.strip())) + + return result