Windows 移动应用程序被任务管理器关闭后将无法运行

发布于 2024-08-25 06:38:23 字数 461 浏览 1 评论 0原文

我继承了一些我一直更新的 Windows Mobile 代码。我遇到了一个奇怪的错误,我希望即使有点模糊,也许它会激发某人的记忆:

运行应用程序(基本上是一个带有 P/Invoke gps 代码的美化的 Forms 应用程序),我切换到任务管理器,然后通过结束任务关闭应用程序。似乎退出正常(没有错误并且从任务管理器中消失)。不幸的是,该应用程序拒绝再次启动,直到我重新启动手机或重新安装 CAB。

更糟糕的是:此错误在 HTC Diamond 上可以重现,但在 HTC HD2 上运行良好(即可以在 EndTask 后再次运行)。

我唯一能想到的是 Dispose() 和任务管理器之间的某种计时竞赛。有什么想法吗?

我也在考虑一种解决方法 - 我确实有一个有效的“退出应用程序”例程,可以正确清理应用程序;我可以捕获 C# 代码中的 EndTask 事件以完成正确的清理吗?

也许我只是错过了痛点......欢迎所有想法:)

I've inherited some windows-mobile code that I've been bringing up-to-date. I've come across a weird bug, and I was hoping that even though a bit vague, maybe it will spark someone's memory:

Running the app (which is basically a glorified Forms app with P/Invoke gps code), I switch to the task manager, and close the app via End Task. Seems to exit fine (no errors and disappears from Task Manager). Unfortunately, the app refuses to start a second time until I reboot the phone or reinstall the CAB.

What's worse: this bug is reproducible on a HTC Diamond, but works fine (ie. can run again after EndTask) on an HTC HD2.

The only thing I can think of is some kind of timing race between a Dispose() and the Task Manager. Any ideas?

I'm also thinking of a workaround - I do have a working "Exit Application" routine that correctly cleans up the app; can I catch the EndTask event in the c# code in order to complete a proper cleanup?

Maybe I'm just missing the pain point... all ideas welcome :)

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

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

发布评论

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

评论(3

不疑不惑不回忆 2024-09-01 06:38:23

当您使用 TaskManager 关闭它时,会发生以下情况:

  1. 应用程序窗体发送 WM_CLOSE 消息
  2. 如果一段时间后它们仍在运行,则使用 TerminateProcess。

如果正在运行的工作线程不退出,则该进程通常不会完全终止。这在 CF 1.0 中非常常见,其中线程的 IsBackground 属性不存在。

由于TaskManager仅枚举表单标题,因此如果您的表单全部关闭,即使进程正在运行,它也不会显示应用程序。当您尝试再次执行时,shell 会检测到它已经在运行,并简单地切换到正在运行(没有 UI)的进程,因此看起来就像什么都没发生一样。

您可以使用远程进程查看器验证此行为。

解决方案是修复工作线程代码以正确退出。通常我使用布尔值或 WaitHandle 来表示它们应该退出。对于创建的所有线程,也应该将 IsBackground 设置为 true。

When you use TaskManager to close it, the following happens:

  1. The app Form(s) are send a WM_CLOSE message
  2. If, after a period of time, they are still running TerminateProcess is used.

If you have a worker thread running that does not exit, the process will often not fully terminate. This was really common in CF 1.0 where the IsBackground property for a thread didn't exist.

Since TaskManager only enumerates Form captions, if your forms are all closed, it will not show the app, even through the process is running. When you try to execute again, the shell detects that it's already running and simply swithes to the running (with no UI) process so it looks like nothing happened.

You can verify this behavior with Remote Process Viewer.

The solution is to fix your worker thread code to exit properly. Typically I use a boolean or a WaitHandle to signal that they should exit. Setting IsBackground to true should also happen for all threads that are created.

打小就很酷 2024-09-01 06:38:23

你的问题已经过去一年了,但这可能就是答案。

我有同样的问题。我的应用程序有 MinimizeBox = False,这在表单的右上角显示一个小 Ok,并且是处理关闭事件的唯一方法(MinimizeBox = True 的十字不会引发 ClosingEvent)。在这种情况下,我取消关闭并执行一些自定义代码并最小化表单,使其看起来像标准的“交叉关闭事物”行为。

问题是,在 htc Diamond 上,当您终止任务时,它会引发相同的关闭事件,而我的代码会再次取消它。奇怪的是,在任务管理器中该应用程序已经消失,但如果您启动原始的 Microsoft 任务管理器 (/windows/taskmgr.exe) 并在菜单中选择“显示进程”,那么您会看到您的应用程序仍在运行。这就是为什么您无法再次启动它的原因。奇怪的是,在 HD2 上,它与关闭事件具有相同的行为,但它似乎也强制对应用程序进行暴力杀戮,所以没问题。

解决方案:
您只需要一点布尔值即可知道您的应用程序是在前台还是在后台,您在表单激活事件中设置为 true ,在停用事件中设置为 false 。在关闭事件中,只有当您的应用程序位于前台时您才能取消,您可以运行您的特殊代码,否则让表单关闭,这是一个杀戮!

[DllImport("coredll.dll")]
static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_MINIMIZED = 6;

public static void MinimizeForm(IntPtr pFormHandle)
{
    ShowWindow(pFormHandle,SW_MINIMIZED);
}

private bool m_IsFormVisible = false;

void m_MainForm_Deactivate(object sender, EventArgs e)
{
    m_IsFormVisible = false;
}

void m_MainForm_Activated(object sender, EventArgs e)
{
    m_IsFormVisible = true;
}

void m_MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (m_IsFormVisible)//very important !
    {
        e.Cancel = true;

        //do something if you want

        //minimize the form yourself
        MinimizeForm(s_Instance.m_MainForm.Handle);
    }
}

it's been a year since your question, but this might be the answer.

I had the same sort of problem. My app has MinimizeBox = False, this shows a small Ok in the right top corner of the form and is the only way to handle the Closing Event (the Cross with MinimizeBox = True doesn't raise ClosingEvent). In this event I cancel the closing and do some custom code and minimize the form so that it looks like the standard ‘Cross close thing’ behavior.

The problem is that on htc diamond, when you kill a task it raises the same closing event, and my code cancels it again. The weird thing is that in task manager the app has disappeared, but if you launch the original Microsoft task manager (/windows/taskmgr.exe) and in the menu select show processes, then you see your app still running. That’s why you can’t launch it again. Strangely on HD2 it has the same behavior with the closing event, but it seems to also force a brute kill on the app, so no problem.

The solution :
You just need a little bool to know if your app is on foreground or on background that you set to true in the form activate event and false on deactivate event. In the closing event, you cancel only if your app is in foreground you can run your special code, otherwise let the form close, it's a kill !!!

[DllImport("coredll.dll")]
static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_MINIMIZED = 6;

public static void MinimizeForm(IntPtr pFormHandle)
{
    ShowWindow(pFormHandle,SW_MINIMIZED);
}

private bool m_IsFormVisible = false;

void m_MainForm_Deactivate(object sender, EventArgs e)
{
    m_IsFormVisible = false;
}

void m_MainForm_Activated(object sender, EventArgs e)
{
    m_IsFormVisible = true;
}

void m_MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    if (m_IsFormVisible)//very important !
    {
        e.Cancel = true;

        //do something if you want

        //minimize the form yourself
        MinimizeForm(s_Instance.m_MainForm.Handle);
    }
}
玩套路吗 2024-09-01 06:38:23

我不知道你的问题到底是什么,但我发现 WinCE 设备往往只允许应用程序的一个实例同时运行。这可能意味着 TaskManager 没有正确清理应用程序,因此它认为它仍在运行并且不会启动另一个副本,或者它实际上可能仍在运行。

尝试在您的应用程序中添加一些代码来检测它是否已经在运行。
还请尝试仔细检查您是否正确清理了存在的所有内容,尤其是线程等,因为窗口关闭应用程序的时间可能与您手动执行的时间不同。

希望有帮助

I don't know exactly what your problem is, but I find WinCE devices tend to only allow one instance of an application to run at once. This could mean that either TaskManager didn't clean up the application properly so it thinks it's still running and doesnt start another copy, OR, it might actually still be running.

Try put some code in your application that detects if it is already running.
Also try double check you are cleaning everything up properly when it exists, especially threads etc as the timing of windows shutting down your application may be different to you doing it manually.

Hope any of that helps

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