Skip to content

Commit 6bb487f

Browse files
committed
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`.
1 parent a5be3e0 commit 6bb487f

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

mbed_lstools/lstools_base.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,19 @@ def scan_html_line_for_target_id(self, line):
720720
return result
721721
return None
722722

723+
def mount_point_ready(self, path):
724+
"""! Check if a mount point is ready for file operations
725+
@return Returns True if the given path exists, False otherwise
726+
"""
727+
result = os.path.exists(path)
728+
729+
if result:
730+
self.debug(self.mount_point_ready.__name__, "Mount point %s is ready" % path)
731+
else:
732+
self.debug(self.mount_point_ready.__name__, "Mount point %s does not exist" % (path))
733+
734+
return result
735+
723736
@staticmethod
724737
def run_cli_process(cmd, shell=True):
725738
"""! Runs command as a process and return stdout, stderr and ret code

mbed_lstools/lstools_win7.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ def get_connected_mbeds(self):
132132
@return Returns [(<mbed_mount_point>, <mbed_id>), ..]
133133
@details Helper function
134134
"""
135-
return [m for m in self.get_mbeds() if os.path.exists(m[0])]
135+
return [m for m in self.get_mbeds() if self.mount_point_ready(m[0])]
136136

137137
def get_mbeds(self):
138138
"""! Function filters devices' mount points for valid TargetID
@@ -198,3 +198,22 @@ def regbin2str(self, regbin):
198198
"""! Decode registry binary to readable string
199199
"""
200200
return filter(lambda ch: ch in string.printable, regbin)
201+
202+
def mount_point_ready(self, path):
203+
"""! Check if a mount point is ready for file operations
204+
@return Returns True if the given path exists, False otherwise
205+
@details Calling the Windows command `dir` instead of using the python
206+
`os.path.exists`. The latter causes a Python error box to appear claiming
207+
there is "No Disk" for some devices that are in the ejected state. Calling
208+
`dir` prevents this since it uses the Windows API to determine if the
209+
device is ready before accessing the file system.
210+
"""
211+
stdout, stderr, retcode = self.run_cli_process('dir %s' % path)
212+
result = True if retcode == 0 else False
213+
214+
if result:
215+
self.debug(self.mount_point_ready.__name__, "Mount point %s is ready" % path)
216+
else:
217+
self.debug(self.mount_point_ready.__name__, "Mount point %s reported not ready with error '%s'" % (path, stderr.strip()))
218+
219+
return result

0 commit comments

Comments
 (0)