Freezing host application (unity freezing)
I'm on windows using Unity 2022.3.28f1 and the current latest commit on this repo. I tried the nuget package and also this, but neither works perfectly inside Unity.
The second time I press play it freezes up and I have to force stop it in task manager.
Found this but i don't know how to fix it right now: https://forum.zer7.com/topic/10126/
Fixed it this way if anyone cares: In WinHidManager.cs
- Change this part in the Run method:
NativeMethods.MSG msg;
while (true)
{
int result = NativeMethods.GetMessage(out msg, hwnd, 0, 0);
if (result == 0 || result == -1) { break; }
NativeMethods.TranslateMessage(ref msg);
NativeMethods.DispatchMessage(ref msg);
}
to:
NativeMethods.MSG msg;
_hwnd = hwnd;
while (true)
{
int result = NativeMethods.GetMessage(out msg, hwnd, 0, 0);
if (result == 0 || result == -1) { break; }
NativeMethods.TranslateMessage(ref msg);
NativeMethods.DispatchMessage(ref msg);
}
- After or before the Run method add this:
static IntPtr _hwnd;
public static void QuitThisBs()
{
uint WM_QUIT = 0x0012;
if (_hwnd != IntPtr.Zero)
{
PostMessage(_hwnd, WM_QUIT, IntPtr.Zero, IntPtr.Zero);
}
}
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
-
In your code where you exit or want to stop it call WinHidManager.QuitThisBs(); (For me I did it in the OnDestroy method Unity provides, but you can call it anywhere even prematurely while game is still running)
-
Done!
Thanks for your report and investigation on the fix! Care to open a PR with these changes?
Thanks @devingDev !
I can confirm that this fix resolves the issues with Unity Editor on Windows (I am using Unity 2021.3.14)
However, I still had problems accessing the “QuitThisBs” function in WinHidManager from one of my own scripts, i.e. from outside. I have therefore added this to WinHidManager:
At the beginning of the Run method:
Application.quitting += OnApplicationQuit;
And a new method:
private void OnApplicationQuit()
{
QuitThisBs();
}
thanks again for this fix, now I don't have to restart unity every 5 seconds ;)
There is also a problem with the MacHidManager:
After reloading the domain/assembly, the IOHIDManager is still running and listen for device changes. Some cleanup is required here.
` protected override void Run(Action readyCallback) { readyCallback(); return;
using (var manager = NativeMethods.IOHIDManagerCreate(IntPtr.Zero).ToCFType())
{
RunAssert(manager.IsSet, "HidSharp IOHIDManagerCreate failed.");
using (var matching = NativeMethods.IOServiceMatching("IOHIDDevice").ToCFType())
{
RunAssert(matching.IsSet, "HidSharp IOServiceMatching failed.");
var devicesChangedCallback = new NativeMethods.IOHIDDeviceCallback(DevicesChangedCallback);
NativeMethods.IOHIDManagerSetDeviceMatching(manager.Handle, matching.Handle);
NativeMethods.IOHIDManagerRegisterDeviceMatchingCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero);
NativeMethods.IOHIDManagerRegisterDeviceRemovalCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero);
var runLoop = NativeMethods.CFRunLoopGetCurrent();
NativeMethods.CFRetain(runLoop);
NativeMethods.IOHIDManagerScheduleWithRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode);
try
{
readyCallback();
NativeMethods.CFRunLoopRun();
}
finally
{
NativeMethods.IOHIDManagerUnscheduleFromRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode);
NativeMethods.CFRelease(runLoop);
}
GC.KeepAlive(devicesChangedCallback);
}
}
}
`
Thanks @devingDev !
I can confirm that this fix resolves the issues with Unity Editor on Windows (I am using Unity 2021.3.14)
However, I still had problems accessing the “QuitThisBs” function in WinHidManager from one of my own scripts, i.e. from outside. I have therefore added this to WinHidManager:
At the beginning of the Run method:
Application.quitting += OnApplicationQuit;And a new method:
private void OnApplicationQuit() { QuitThisBs(); }thanks again for this fix, now I don't have to restart unity every 5 seconds ;)
How did you add Application.quitting to the Run method in WinHidManager? I do not seem to have one?
@OnurRafet
Just like this, right at the start a register to the quitting event, only works with in Unity because "Application" is from using UnityEngine;
private void OnApplicationQuit()
{
QuitThisBs();
}
protected override void Run(Action readyCallback)
{
UnityEngine.Application.quitting += OnApplicationQuit;
// Rest of the run function ...
}