まず、次の 2 つの同様の質問を見つけました。
Python ctypes で Windows API に構造を渡す
最初のものには受け入れられた答えがなく、別のプロセスで何かをしているとは思いません。2 つ目は、pointer() と byref() を指摘しているだけで、どちらも使用しようとしても役に立ちませんでした。
さて、私の質問に進みます:
独自の pReportInformation (最初のデータ値が独自のサイズである構造体へのポインター) を使用して関数 WERReportCreate を呼び出そうとしています。これは、やり方によってはさまざまな方法で失敗しますが、正しく行う方法がわかりません。要件の 1 つは、構造体がそれ自体のサイズを認識しているということであり、これをプログラムで決定する方法がわかりません (ただし、それが唯一の問題である場合は、今までに正しい値を推測していたと思います)。 )。WER API からの関連情報を以下に示します。
HRESULT WINAPI WerReportCreate(
__in PCWSTR pwzEventType,
__in WER_REPORT_TYPE repType,
__in_opt PWER_REPORT_INFORMATION pReportInformation,
__out HREPORT *phReportHandle
);
(完全な情報はhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb513625%28v=vs.85%29.aspxにあります)
typedef struct _WER_REPORT_INFORMATION {
DWORD dwSize;
HANDLE hProcess;
WCHAR wzConsentKey[64];
WCHAR wzFriendlyEventName[128];
WCHAR wzApplicationName[128];
WCHAR wzApplicationPath[MAX_PATH];
WCHAR wzDescription[512];
HWND hwndParent;
} WER_REPORT_INFORMATION, *PWER_REPORT_INFORMATION;
(完全な情報はhttp://msdn.microsoft.com/en-us/library/windows/desktop/bb513637%28v=vs.85%29.aspxにあります)
これは私が試したコードです:
import ctypes
import ctypes.wintypes
class ReportInfo( ctypes.Structure):
_fields_ = [ ("dwSize", ctypes.wintypes.DWORD),
("hProcess", ctypes.wintypes.HANDLE),
("wzConsentKey", ctypes.wintypes.WCHAR * 64),
("wzFriendlyEventName", ctypes.wintypes.WCHAR * 128),
("wzApplicationName", ctypes.wintypes.WCHAR * 128),
("wzApplicationPath", ctypes.wintypes.WCHAR * ctypes.wintypes.MAX_PATH),
("wzDescription", ctypes.wintypes.WCHAR * 512),
("hwndParent", ctypes.wintypes.HWND) ]
def genReportInfo():
import os
size = 32 #Complete SWAG, have tried many values
process = os.getpid()
parentwindow = ctypes.windll.user32.GetParent(process)
werreportinfopointer = ctypes.POINTER(ReportInfo)
p_werinfo = werreportinfopointer()
p_werinfo = ReportInfo(size, process, "consentkey", "friendlyeventname", "appname", "apppath", "desc", parentwindow)
return p_werinfo
if __name__ == '__main__':
reporthandle = ctypes.wintypes.HANDLE()
res = ctypes.wintypes.HRESULT()
### First pass NULL in as optional parameter to get default behavior ###
p_werinfo = None
res = ctypes.windll.wer.WerReportCreate(u'pwzEventType', 2, p_werinfo, ctypes.byref(reporthandle))
print "Return Code",res,"\nHandle",reporthandle #Return Code 0, reporthandle is correct (verified by submitting report in a different test)
p_werinfo = genReportInfo() # Create our own struct
### Try Again Using Our Own Struct (via 'byref') ###
res = ctypes.windll.wer.WerReportCreate(u'pwzEventType', 2, ctypes.byref(p_werinfo), ctypes.byref(reporthandle))
print "Return Code",res,"\nHandle",reporthandle #Return Code Nonzero, reporthandle is None
### Try Again Using Our Own Struct (directly) ###
res = ctypes.windll.wer.WerReportCreate(u'pwzEventType', 2, p_werinfo, ctypes.byref(reporthandle))
print "Return Code",res,"\nHandle",reporthandle #Exception Occurs, Execution halts
そして、これは私が得る出力です:
Return Code 0
Handle c_void_p(26085328)
Return Code -2147024809
Handle c_void_p(None)
Traceback (most recent call last):
File "test.py", line 40, in <module>
res = ctypes.windll.wer.WerReportCreate(u'pwzEventType', s.byref(reporthandle))
WindowsError: exception: access violation writing 0x0000087C
null を渡すと機能するが、実際に (私の?) 構造体を渡すと機能しないという事実は、次の 3 つの問題のうちの 1 つを抱えていることを示唆しています。 wzConsentKey が正しく定義されている)、または構造体のサイズを正しく把握していない (実際には struct.calcsize をさまざまなオプションで使用して初期推測を取得し、ランダムに 1 を加算および減算しています)、または (参照を正しく渡していません) ?) 構造に。
ここで行き止まりになりました。任意の助けをいただければ幸いです (私の質問の明確さ、書式設定、または品質を改善する方法についての提案も同様です。これが私の最初の投稿です)。