我有一个Java应用程序,我从控制台运行,然后控制台执行另一个Java进程.我想获得该子进程的线程/堆转储.
在Unix上,我可以做一个kill -3 <pid>但是在Windows AFAIK上获取线程转储的唯一方法是在控制台中使用Ctrl-Break.但这只会让我转移父进程,而不是孩子.
有没有另一种方法来获得堆转储?
让我们假设我们有一个用python编写的这样一个简单的守护进程:
def mainloop():
while True:
# 1. do
# 2. some
# 3. important
# 4. job
# 5. sleep
mainloop()
Run Code Online (Sandbox Code Playgroud)
然后我们使用start-stop-daemon默认的send SIGTERM(TERM)信号进行守护--stop.
我们假设当前执行的步骤是#2.在这个时刻,我们正在发送TERM信号.
会发生什么是执行立即终止.
我发现我可以处理信号事件,signal.signal(signal.SIGTERM, handler)但问题是它仍然会中断当前执行并将控制传递给handler.
所以,我的问题是-它可以不中断当前执行,但处理TERM(?)在独立的线程信号,使我能够设置shutdown_flag = True,使mainloop()有机会停止正常?
我有一个测试工具(用Python编写),需要通过发送来关闭被测程序(用C语言编写)^C.在Unix上,
proc.send_signal(signal.SIGINT)
Run Code Online (Sandbox Code Playgroud)
工作得很好.在Windows上,会抛出错误("不支持信号2"或类似的东西).我正在使用Python 2.7 for Windows,所以我觉得我应该能够做到
proc.send_signal(signal.CTRL_C_EVENT)
Run Code Online (Sandbox Code Playgroud)
但这根本不起作用.我需要做什么?这是创建子进程的代码:
# Windows needs an extra argument passed to subprocess.Popen,
# but the constant isn't defined on Unix.
try: kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
except AttributeError: pass
proc = subprocess.Popen(argv,
stdin=open(os.path.devnull, "r"),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
**kwargs)
Run Code Online (Sandbox Code Playgroud) 我想知道,在摆弄了SendInput,SendKeys,PostMessage,SendMessage,SendNotifyMessage,keybd_event等等各种问题之后.为了找到这个...尝试将键盘输入发送到另一个非前台进程是相当挑剔和不可靠的.
我尝试了一种SendInput的方法,我在其中欺骗Z顺序(保持当前窗口在顶部)并快速前进第三方窗口,发送输入,并重新前景我的窗口.其中最终失败了,而且,不知何故,不知道为什么,设法同时也在我的窗口上触发键盘而不是前景(导致在两个窗口之间发送和接收的无限循环,直到我设法关闭该过程).
我尝试过SendMessage和PostMessage的不同组合.一个用于向下,一个用于向上,因为同时使用向下和向上导致问题,例如PostMessage用于两者,导致密钥在接收窗口上复制.或两者的SendMessage,这导致文本输入问题,但其他功能正常.用于keydown的SendMessage和用于keyUp的PostMessage适用于所有功能,但可靠性率急剧下降,并且在关键事件中增加了延迟.只有用于keydown的PostMessage和用于keyup的SendMessage的组合设法做了一些有用的事情,可能有5-10%的密钥注册失败率.对于SentNotifyMessage也是如此(就可靠性而言,其行为与SendMessage基本相同).
基本上,我已经结束了,我想知道直接在目标窗口中注入一个钩子,并做一些伏都教以这种方式向它发送击键,绕过消息队列等.这样做将会不会触发全局键事件,只会影响目标窗口.唯一的问题是,当涉及到注射/挂钩等时,我是不可知的.所以我转向你,社区.
哇呢?
我有一个应用程序A,我希望能够在配置文件中调用用户指定的任意其他进程.
批处理脚本B是用户希望由A调用的一个这样的过程.B设置一些环境变量,显示一些消息并调用编译器C来完成一些工作.
Windows是否为任意进程提供了一种标准的方式来彻底终止?假设A在控制台中运行并接收CTRL + C. 它可以传递给B和C吗?假设A在窗口中运行并且用户试图关闭窗口,它可以取消B和C吗?
TerminateProcess是一个选项,但不是一个很好的选项.如果A在B上使用TerminateProcess,则C继续运行.如果C长时间运行,这可能会导致令人讨厌的问题,因为我们可能会启动另一个C实例来操作相同的文件,而C的第一个实例仍在秘密工作.此外,TerminateProcess不会导致干净的退出.
GenerateConsoleCtrlEvent听起来不错,并且可以在控制台中运行所有内容时工作,但文档说您只能将CTRL + C发送到您自己的控制台,因此如果A在窗口中运行则无济于事.
在Windows上是否有任何等效的SIGINT?我很想找到像这样的文章:http://www.cons.org/cracauer/sigint.html for Windows.
我经常在Linux和Mac上向开发人员展示jhat,jps和jstack工具集.但是,一位开发人员最近表示,如果相关的Java应用程序作为Windows服务运行,则这些在Windows中无法使用.
一个太阳提交的bug说的非常相似,但由于不活动而被关闭.
我已经为自己测试了这一点,但事实上它似乎是正确的,尽管我几乎无法相信.这是设置:
这在Windows XP,Windows 2003 Server和Windows 7下可重现.Java版本1.5和1.6产生相同的结果.
有没有办法从终端,即使以管理员身份登录,"sudo up"获取JPS和其他工具来查看java服务?
我有一个带有关闭钩子的Java应用程序.当我在IntelliJ中运行应用程序并单击" 退出"按钮(与不会导致关闭挂钩的" 停止"按钮相反)时,将执行关闭挂钩.
我需要能够从Windows批处理文件中关闭该进程.我taskkill没有运气尝试了各种命令组合(假设PID为1234):
taskkill /pid 1234 /t
taskkill /pid 1234 /f /t
Run Code Online (Sandbox Code Playgroud)
有没有办法让我从MS批处理文件中终止Java进程,并执行Java关闭挂钩?
该应用程序在Windows服务器上运行.
我正在努力去GenerateConsoleCtrlEvent上班。这是我想出的最小示例:
#include <Windows.h>
static BOOL WINAPI handler(DWORD CtrlType)
{
return TRUE;
}
int main()
{
if (!SetConsoleCtrlHandler(&handler, TRUE))
{
throw 1;
}
STARTUPINFO si = {0};
DWORD dwStartupFlags = 0;
PROCESS_INFORMATION pi;
if (!CreateProcess(
NULL,
"cmd.exe",
NULL,
NULL,
FALSE,
dwStartupFlags,
NULL, // environ
NULL, // cwd
&si,
&pi))
{
throw 1;
}
CloseHandle(pi.hThread);
DWORD exitCode;
while(true)
{
switch (WaitForSingleObject(pi.hProcess, 1000 * 10))
{
case WAIT_TIMEOUT:
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
//WaitForSingleObject(pi.hProcess, INFINITE);
break;
case WAIT_OBJECT_0:
GetExitCodeProcess(pi.hProcess, &exitCode);
return exitCode;
}
} …Run Code Online (Sandbox Code Playgroud) 开始一个过程——
ProcessStartInfo psi = new ProcessStartInfo("G:\\SampleWinApp.exe");
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
Process prcs = Process.Start(psi);
Run Code Online (Sandbox Code Playgroud)
使用 PostMessage发送WM_CLOSE
const int WM_CLOSE = 0x0010;
public void SendCloseSignal(Process proc)
{
uint uiPid = (uint) proc.Id;
bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
if (!bResult && Marshal.GetLastWin32Error() == 0) {
object objWnd = processWnd[uiPid];
if (objWnd != null) {
IntPtr ptrWnd = (IntPtr) objWnd;
PostMessage(ptrWnd, WM_CLOSE, 0, 0);
return;
}
}
foreach (ProcessThread thread in proc.Threads) {
PostThreadMessage((uint) thread.Id, WM_CLOSE, UIntPtr.Zero, IntPtr.Zero);
} …Run Code Online (Sandbox Code Playgroud) windows ×7
java ×4
winapi ×3
c# ×2
python ×2
64-bit ×1
batch-file ×1
c#-4.0 ×1
cmd ×1
copy-paste ×1
daemon ×1
heap-dump ×1
jvm ×1
process ×1
sendmessage ×1
signals ×1
sigterm ×1
subprocess ×1
thread-dump ×1
websphere ×1