可以“Windows 错误报告”吗?用于非致命的 Java 问题?

发布于 2024-12-21 13:36:50 字数 355 浏览 2 评论 0原文

我想知道是否有办法从 Java 程序“内部”使用 Windows 错误报告?

换句话说,使用该机制将异常报告回中央位置,而不会导致实际的 JVM 崩溃(据我所知,这是首先触发此问题的原因)。

这里的想法是让从 Windows 用户收集错误报告变得更容易。


我也想听听它是否可以成为受控关闭的一部分。即不是 JVM 崩溃,而是 Java 程序的正常、受控退出。


经过深思熟虑,我认为创建一组文本文件(或者可能只是通过管道传入单个文本流)到位于我们文件系统部分内的小型 Windows 应用程序就足以满足我们的目的。然后,所述 Windows 应用程序会显着崩溃,并导致发送包含我们提供的文本的报告。那行得通吗?

I was wondering if there was a way to use Windows Error Reporting from "inside" a Java program?

In other words, use the mechanism to report exceptions back to a central location without having the actual JVM crash (which to my understanding is what triggers this in the first place).

The idea here is to make it easier to collect bug reports from Windows users.


I'd like to hear too if it can be part of a controlled shutdown. I.e. not a JVM crash but a normal, controlled exit from a Java program.


After thinking it over, I think that it would be sufficient for our purposes to create a set of text files (or perhaps just pipe in a single text stream) to a tiny Windows application located inside our part of the file system. Said Windows application then crashes prominently and cause a report to be sent including the text provided by us. Would that work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独自唱情﹋歌 2024-12-28 13:36:50

您绝对可以使用 wer.dll 中附带的 Windows 错误报告 API 作为 Win32 API 的一部分。

从 Java 调用基于 DLL 的函数的最佳方法是使用积极开发的 Java Native Access 项目

为了进行所需的 Win32 API 调用,我们需要至少向 JNA 传授这些函数:

HRESULT WINAPI WerReportCreate(
  __in      PCWSTR pwzEventType,
  __in      WER_REPORT_TYPE repType,
  __in_opt  PWER_REPORT_INFORMATION pReportInformation,
  __out     HREPORT *phReportHandle
);

HRESULT WINAPI WerReportSubmit(
  __in       HREPORT hReportHandle,
  __in       WER_CONSENT consent,
  __in       DWORD dwFlags,
  __out_opt  PWER_SUBMIT_RESULT pSubmitResult
);

以及这个结构:

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;

为此,我们将创建 WER.java:

package com.sun.jna.platform.win32;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Wer extends StdCallLibrary {
    Wer INSTANCE = (Wer) Native.loadLibrary("wer", Wer.class,
                                                W32APIOptions.DEFAULT_OPTIONS);

    public static class HREPORT extends HANDLE {
        public HREPORT() { }
        public HREPORT(Pointer p) { super(p); }
        public HREPORT(int value) { super(new Pointer(value)); }
    }

    public static class HREPORTByReference extends ByReference {
        public HREPORTByReference() {
            this(null);
        }

        public HREPORTByReference(HREPORT h) {
            super(Pointer.SIZE);
            setValue(h);
        }

        public void setValue(HREPORT h) {
            getPointer().setPointer(0, h != null ? h.getPointer() : null);
        }

        public HREPORT getValue() {
            Pointer p = getPointer().getPointer(0);
            if (p == null)
                return null;
            if (WinBase.INVALID_HANDLE_VALUE.getPointer().equals(p)) 
                return (HKEY) WinBase.INVALID_HANDLE_VALUE;
            HREPORT h = new HREPORT();
            h.setPointer(p);
            return h;
        }
    }

    public class WER_REPORT_INFORMATION extends Structure {
        public DWORD dwSize;
        public HANDLE hProcess;
        public char[] wzConsentKey = new char[64];
        public char[] wzFriendlyEventName = new char[128];
        public char[] wzApplicationName = new char[MAX_PATH];
        public char[] wzDescription = new char[512];
        public HWND hwndParent;

        dwSize = new DWORD(size());
    }

    public abstract class WER_REPORT_TYPE {
        public static final int WerReportNonCritical = 0;
        public static final int WerReportCritical = 1;
        public static final int WerReportApplicationCrash = 2;
        public static final int WerReportApplicationHang = 3;
        public static final int WerReportKernel = 4;
        public static final int WerReportInvalid = 5;
    }

    HRESULT WerReportCreate(String pwzEventType, int repType, WER_REPORT_INFORMATION pReportInformation, HREPORTByReference phReportHandle);
    HRESULT WerReportSubmit(HREPORT hReportHandle, int consent, DWORD dwFlags, WER_SUBMIT_RESULT.ByReference pSubmitResult);
}

我刚刚从 MSDN 文档中将其组合在一起几分钟——以防不完整或不正确,有大量 JNA 网站上的示例非常好的文档

为了运行 JNA,您需要 jna.jarplatform.jar,您也可以从 JNA 网站获取它们。

You can definitely use the Windows Error Reporting API that ships in wer.dll as part of the Win32 API.

The best way to call DLL-based functions from Java is using the actively developed Java Native Access project.

In order to make the required Win32 API calls, we'll need to teach JNA about at least these functions:

HRESULT WINAPI WerReportCreate(
  __in      PCWSTR pwzEventType,
  __in      WER_REPORT_TYPE repType,
  __in_opt  PWER_REPORT_INFORMATION pReportInformation,
  __out     HREPORT *phReportHandle
);

HRESULT WINAPI WerReportSubmit(
  __in       HREPORT hReportHandle,
  __in       WER_CONSENT consent,
  __in       DWORD dwFlags,
  __out_opt  PWER_SUBMIT_RESULT pSubmitResult
);

and also this struct:

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;

To do this, we'll create WER.java:

package com.sun.jna.platform.win32;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Wer extends StdCallLibrary {
    Wer INSTANCE = (Wer) Native.loadLibrary("wer", Wer.class,
                                                W32APIOptions.DEFAULT_OPTIONS);

    public static class HREPORT extends HANDLE {
        public HREPORT() { }
        public HREPORT(Pointer p) { super(p); }
        public HREPORT(int value) { super(new Pointer(value)); }
    }

    public static class HREPORTByReference extends ByReference {
        public HREPORTByReference() {
            this(null);
        }

        public HREPORTByReference(HREPORT h) {
            super(Pointer.SIZE);
            setValue(h);
        }

        public void setValue(HREPORT h) {
            getPointer().setPointer(0, h != null ? h.getPointer() : null);
        }

        public HREPORT getValue() {
            Pointer p = getPointer().getPointer(0);
            if (p == null)
                return null;
            if (WinBase.INVALID_HANDLE_VALUE.getPointer().equals(p)) 
                return (HKEY) WinBase.INVALID_HANDLE_VALUE;
            HREPORT h = new HREPORT();
            h.setPointer(p);
            return h;
        }
    }

    public class WER_REPORT_INFORMATION extends Structure {
        public DWORD dwSize;
        public HANDLE hProcess;
        public char[] wzConsentKey = new char[64];
        public char[] wzFriendlyEventName = new char[128];
        public char[] wzApplicationName = new char[MAX_PATH];
        public char[] wzDescription = new char[512];
        public HWND hwndParent;

        dwSize = new DWORD(size());
    }

    public abstract class WER_REPORT_TYPE {
        public static final int WerReportNonCritical = 0;
        public static final int WerReportCritical = 1;
        public static final int WerReportApplicationCrash = 2;
        public static final int WerReportApplicationHang = 3;
        public static final int WerReportKernel = 4;
        public static final int WerReportInvalid = 5;
    }

    HRESULT WerReportCreate(String pwzEventType, int repType, WER_REPORT_INFORMATION pReportInformation, HREPORTByReference phReportHandle);
    HRESULT WerReportSubmit(HREPORT hReportHandle, int consent, DWORD dwFlags, WER_SUBMIT_RESULT.ByReference pSubmitResult);
}

I just knocked that together from the MSDN dcoumentation in a few minutes--in case it's incomplete, or incorrect, there are tons of examples and pretty good documentation on the JNA web site.

In order to run JNA, you'll need jna.jar and platform.jar, which you can also grab from the JNA web site.

泪之魂 2024-12-28 13:36:50

过去,我必须对 Java 和 .NET 之间的互操作性进行编程,因此我开始进行一些关于使用 .NET 与 WER 交互的研究,目的是看看是否可以在 .NET 应用程序中与 WER 交互然后您就可以与 Java 进行交互。有趣的是,我在 SOF 上看到了这篇文章 - Is there a . Net API for Windows Error Reporting

这篇文章提供了一些与 WER 交互相关的有用信息。

我知道这篇文章是围绕使用 .NET 对抗 WER 展开的,但是当您尝试与本机 Windows 功能进行交互时,我建议使用 .NET 与其进行交互,因为使用 .NET 与本机 Windows 资源进行交互比使用 .NET 更容易它是用 Java 实现的(通常只需要 Java 中一半的代码)。然后,您可以使用 Java 连接到 .NET 应用程序(可能最好设置为 Windows 服务)(例如,您可以在 .NET 应用程序中使用临时“触发”文件来指示 .NET 应用程序何时完成它的工作)。处理;然后 Java 应用程序可以探测该“触发”文件何时创建并从那里继续...)。

不过,正如该帖子中已接受的答案所建议的那样,最好使用 Windows Quality Online Services,而不是编写与 WER 交互的内容,因为 WER 似乎并不适合由其他应用程序使用。

I've had to program inter-operability between Java and .NET in the past, so I started to do some research on using .NET to interact with WER with the intention to see if it's possible to interact with WER in a .NET app that you could then interface with Java. Interestingly, I came across this post on SOF - Is there a .Net API for Windows Error Reporting

That post has some good information related to interacting with WER.

I know that the post revolves around using .NET against WER, but as you're trying to interact with native Windows functionality, I recommend using .NET to interact with it as it's SO much easier to interact with native Windows resources using .NET than it is with Java (and it usually takes half the code it would in Java). You could then interface to the .NET app (might be best set up as a Windows service) with Java (for instance, you could use temporary "trigger" files in the .NET app to indicate when the .NET app is done with it's processing; the Java app could then probe to see when that "trigger" file has been created and continue from there...).

As the accepted answer in that post recommends, though, it might be best to use Windows Quality Online Services instead of programming something to interact with WER as it appears that WER is not meant to be used by other applications.

夕色琉璃 2024-12-28 13:36:50

您可以与本机 WER 库函数进行互操作。

以下是相关的 MSDN 文档:

  1. 创建报告
  2. 提交报告

也许具有更多 Java 互操作经验的人可以为您提供代码示例,不幸的是,我更喜欢 .NET。

编辑:

我做了一些更多的研究,我认为你可以尝试使用 GlueGen 或 SWIG 生成 Java 绑定。您必须下载 Windows SDK 才能获取 werapi如果要生成绑定,请使用头文件。

You could interop with the native WER library functions.

Here is the relevant MSDN documentation:

  1. Creating a report
  2. Submitting a report

Perhaps someone with more Java-interop experience can provide you with code examples, I'm more of a .NET guy unfortunately.

EDIT:

I did some more research, and I think you could try using GlueGen or SWIG to generate the Java bindings. You will have to download the Windows SDK to get the werapi header file if you want to generate the bindings.

云雾 2024-12-28 13:36:50

您的意思是说,WER 应该用它来记录日志,而不是创建 hs_err_pid*.log 文件?或者您打算记录可以在 WER 中的 Java 程序中处理的任何异常的详细异常消息?

如果情况是 1 那么显然你不能巧妙地做到这一点。您可能始终运行一个单独的守护进程来查找创建的 hs_err_pid*.log -> 使用外部库解释它 -> 使用上面建议的 WER API 将其写入 WER 记录中。

如果是第二种情况,那么您可能需要进行 JNI 调用并调用 WER API 以在 WER 中编写内容。

Do you mean to say that instead of hs_err_pid*.log files being created WER should log the logs with it ??Or you intent to log the detailed exception message of any exception which can be handled in Java programs in WER ?

If the case is 1 then obviously you can't do it neatly. You may have a separate daemon running all the time to look for hs_err_pid*.log created->interpret it using external libraries->use WER APIs suggested above to write it in WER recorords.

If the case is 2nd one then you may like to make a JNI call and have the calls made to WER APIs to write stuff in WER.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文