如何关闭在Python / pythoncom / comtypes中打开的Windows Portable Device IStream

时间:2018-05-30 18:08:28

标签: python-3.x ctypes wpd comtypes pythoncom

我在python中使用带有pythoncom和comtypes的Windows便携设备。

我遇到了麻烦,因为当我请求WPD_RESOURCE_THUMBNAIL资源时,一些Android设备返回一个“方形”缩略图,而原始图像有16:9格式(或4:3 ......)。

然后我尝试请求WPD_RESOURCE_DEFAULT资源以便从EXIF数据中获取缩略图:所以不需要读取整个文件,一旦我获得缩略图的EXIF标记,我就可以停止读取并跳转到下一个文件

我可以从EXIF获取第一个文件的缩略图。在第二个文件中,我遇到了GetStream()方法。它只是挂起。 我想是因为前一次通话的IStream没有关闭/处理。

您是否知道如何强制使用此IStream的Dispose / Close?

这就是我在代码中所做的:

optimalTransferSizeBytes, fileStream = resources.GetStream(
                    self.objectID,
                    WPD_RESOURCE_DEFAULT,
                    ctypes.c_ulong(0),
                    optimalTransferSizeBytes,
                    pFileStream
                )

提前感谢您对此提出任何建议。

修改: 由于我没有找到其他方法来中断流并释放所有资源,因此我最终读取了WPD_RESOURCE_DEFAULT的整个流。它有点慢,但它更安全,因为应用程序也在大屏幕上运行,使用EXIF的缩略图可能导致屏幕上的图像质量不佳。所以我决定为此目的读取WPD_RESOURCE_DEFAULT的整个流,并在此之外的某个地方加速代码。 谢谢@ShadowRanger的支持。

1 个答案:

答案 0 :(得分:0)

UnmanagedMemoryStream类型has a Dispose method,如果您的图书馆为您公开了所有方法,那么简单的fileStream.Dispose()应该有效。为了安全起见,您需要实现上下文管理器包装器以允许使用with语句,或者更少使用Python,但更简单地说,使用try / finally,例如:

optimalTransferSizeBytes, fileStream = resources.GetStream(
                    self.objectID,
                    WPD_RESOURCE_DEFAULT,
                    ctypes.c_ulong(0),
                    optimalTransferSizeBytes,
                    pFileStream
                )
try:
    ... do stuff with fileStream ...
finally:
    fileStream.Dispose()

或者,你可以make your own context manager to perform disposal

from contextlib import contextmanager

@contextmanager
def disposing(disposable):
    try:
        yield disposable
    finally:
        disposable.Dispose()

这将允许更好的代码:

optimalTransferSizeBytes, fileStream = resources.GetStream(
                    self.objectID,
                    WPD_RESOURCE_DEFAULT,
                    ctypes.c_ulong(0),
                    optimalTransferSizeBytes,
                    pFileStream
                )
with disposing(fileStream):
    ... do stuff with fileStream ...