enthought / comtypes

A pure Python, lightweight COM client and server framework, based on the ctypes Python FFI package.
Other
290 stars 96 forks source link

Had this issue since installed a certain update in windows 11, is this a windows issue or is it a comtypes issue? OSError: exception: access violation writing #476

Open ninjatall12 opened 1 year ago

ninjatall12 commented 1 year ago

Comtypes.txt

junkmd commented 1 year ago

I think that your report is similar to the following issue.

89, #98, #193

Can you tell me what COM library you were trying to use and how it worked in environments other than Windows 11?

And, error messages and code snippets should be listed as highlighting-code-blocks as shown below.

https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks

ninjatall12 commented 1 year ago

It is not my program but a third party library that i am using called DXcam which is a screenshot library that wraps around Desktop Duplication Api to take screenshots.

The provider of the third party library i believe is no longer maintaining the library and i want to learn how to fix some issues.

https://github.com/ra1nty/DXcam/search?q=comtypes

All i know it happens when i alt tab out of a game using vulkan or directx11 have not tested other games.

I know it is not your job to go read and diagnose someone elses code and i apologise in advance.

junkmd commented 1 year ago

It doesn't matter that it is not your code.

What I would like to know is at what point did the error occur when you tried to "take screenshots" using DXcam.

I want "code snippet that reproduces the issue".

For example, if you "got an IndexError with a list", I want the code similar to below.

>>> foo = []
>>> foo[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
ninjatall12 commented 1 year ago
 except comtypes.COMError as ce:
            if ctypes.c_int32(DXGI_ERROR_ACCESS_LOST).value == ce.args[0]:
                return False
            if ctypes.c_int32(DXGI_ERROR_WAIT_TIMEOUT).value == ce.args[0]:
                self.updated = False
                return True
            else:
                raise ce
        try:
            self.texture = res.QueryInterface(ID3D11Texture2D)
        except comtypes.COMError as ce:
            self.duplicator.ReleaseFrame()
        self.updated = True
        return True

I am 100% sure that the error lies between these codes. as the error only occurs when switching tabs

junkmd commented 1 year ago

OK, I see where the error might be occurring. Are you sure it is the code block in the permalink below? https://github.com/ra1nty/DXcam/blob/e578c0d8bfcabf50a65c4dac764e0d8b318494b1/dxcam/core/duplicator.py#L21-L43

How were you calling the function or class when this error occurred? We need it so that community members, including myself, can try to reproduce the error.

ninjatall12 commented 1 year ago

The function was called by the _grab function but here is also the grab function incase any context is needed. These are located in the dxcam.py file

def grab(self, region: Tuple[int, int, int, int] = None):
        if region is None:
            region = self.region
        self._validate_region(region)
        frame = self._grab(region)
        return frame

    def _grab(self, region: Tuple[int, int, int, int]):
        if self._duplicator.update_frame():
            if not self._duplicator.updated:
                return None
            self._device.im_context.CopyResource(
                self._stagesurf.texture, self._duplicator.texture
            )
            self._duplicator.release_frame()
            rect = self._stagesurf.map()
            frame = self._processor.process(
                rect, self.width, self.height, region, self.rotation_angle
            )
            self._stagesurf.unmap()
            return frame
        else:
            self._on_output_change()
            return None        
junkmd commented 1 year ago

What I am asking is how you are using DXcam.

For example, if you are "using a list and an IndexError was raised", I don't want the source code that implements the list of Python, I want code that can reproduce the situation in which the error actually occurred, such as the following.

>>> spam = ["foo", "bar", "baz"]
>>> spam[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
vasily-v-ryabov commented 1 year ago

First thanks for letting me know about such library DXCam and Duplication API. It might be useful to pywinauto project where we use Pillow to take screenshots (not sure it would work in DirectX games).

Regarding the issue, it seems error reporting could be improved in DXCam project. OSError usually means some error code returned by a system call, and error text description can be obtained by another system call (GetLastError or something like that). I can't promise I will have time for this issue soon. But it's interesting.

vasily-v-ryabov commented 1 year ago

Well, sorry I read the text log attached to the first post in this thread, and there is already such information handled by comtypes. It looks like we need to dive into DXCam code anyway. It could be some aligning issue (could be in comtypes too) or wrong sequence of Duplication API calls or missing error handling if some errors are expected.

junkmd commented 4 months ago

Is there an update on this issue?