mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-22 17:29:18 +01:00
Changed IPC communication to use memory mapped memory instead of physical file to store the name of the DS4Form window class.
This commit is contained in:
parent
75d08fe76c
commit
c6daa18032
@ -59,7 +59,7 @@ namespace DS4Windows.Forms
|
||||
private ManagementEventWatcher managementEvWatcher;
|
||||
private DS4Forms.LanguagePackComboBox languagePackComboBox1;
|
||||
private AdvancedColorDialog advColorDialog;
|
||||
Dictionary<Control, string> hoverTextDict = new Dictionary<Control, string>();
|
||||
Dictionary<Control, string> hoverTextDict = new Dictionary<Control, string>();
|
||||
// 0 index is used for application version text. 1 - 4 indices are used for controller status
|
||||
string[] notifyText = new string[5]
|
||||
{ "DS4Windows v" + FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion,
|
||||
@ -87,9 +87,6 @@ namespace DS4Windows.Forms
|
||||
[DllImport("psapi.dll")]
|
||||
private static extern uint GetModuleFileNameEx(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||
|
||||
public DS4Form(string[] args)
|
||||
{
|
||||
Global.FindConfigLocation();
|
||||
@ -391,16 +388,7 @@ namespace DS4Windows.Forms
|
||||
if (!(StartMinimized || mini))
|
||||
Form_Resize(null, null);
|
||||
|
||||
// Write current window class name as InterProcessCommunication identifier. The IPC classname is used in WM_DATACOPY messaging interface. .NET WinForms creates a semi-random clas names per application.
|
||||
StringBuilder wndClassNameStr = new StringBuilder(256);
|
||||
if (GetClassName(this.Handle, wndClassNameStr, wndClassNameStr.Capacity) != 0 && wndClassNameStr.Length > 0)
|
||||
{
|
||||
if (System.IO.File.Exists(appdatapath + "\\IPCClassName.dat") && System.IO.File.ReadAllText(appdatapath + "\\IPCClassName.dat") == wndClassNameStr.ToString())
|
||||
wndClassNameStr.Clear(); // The wnd classname is still the same, so no need to re-write it
|
||||
|
||||
if(wndClassNameStr.Length > 0)
|
||||
System.IO.File.WriteAllText(appdatapath + "\\IPCClassName.dat", wndClassNameStr.ToString());
|
||||
}
|
||||
Program.CreateIPCClassNameMMF(this.Handle);
|
||||
|
||||
Program.rootHub.Debug += On_Debug;
|
||||
|
||||
|
@ -6,11 +6,16 @@ using Process = System.Diagnostics.Process;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Text;
|
||||
|
||||
namespace DS4Windows
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "FindWindow")]
|
||||
private static extern IntPtr FindWindow(string sClass, string sWindow);
|
||||
|
||||
@ -36,6 +41,9 @@ namespace DS4Windows
|
||||
private static Thread controlThread;
|
||||
private static Form ds4form;
|
||||
|
||||
private static MemoryMappedFile ipcClassNameMMF = null; // MemoryMappedFile for inter-process communication used to hold className of DS4Form window
|
||||
private static MemoryMappedViewAccessor ipcClassNameMMA = null;
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
@ -86,15 +94,14 @@ namespace DS4Windows
|
||||
|
||||
IntPtr hWndDS4WindowsForm = IntPtr.Zero;
|
||||
|
||||
Global.FindConfigLocation();
|
||||
if (args[i].Length > 0 && args[i].Length <= 256 && !string.IsNullOrEmpty(Global.appdatapath) && System.IO.File.Exists(Global.appdatapath + "\\IPCClassName.dat"))
|
||||
if (args[i].Length > 0 && args[i].Length <= 256)
|
||||
{
|
||||
// Find the main DS4Form window handle and post WM_COPYDATA inter-process message. IPCClasName.dat file was created by the main DS4Windows process
|
||||
// and it contains the name of the DS4Form .NET window class name string (the hash key part of the string is dynamically generated by .NET engine and it may change,
|
||||
// so that's why the main process re-creates the file if the window class name is changed by .NET framework). Finding the WND handle usig both class name and window name
|
||||
// limits chances that WM_COPYDATA message is sent to a wrong window.
|
||||
|
||||
hWndDS4WindowsForm = FindWindow(System.IO.File.ReadAllText(Global.appdatapath + "\\IPCClassName.dat"), "DS4Windows");
|
||||
hWndDS4WindowsForm = FindWindow(ReadIPCClassNameMMF(), "DS4Windows");
|
||||
if (hWndDS4WindowsForm != IntPtr.Zero)
|
||||
{
|
||||
COPYDATASTRUCT cds;
|
||||
@ -178,6 +185,9 @@ namespace DS4Windows
|
||||
while (testThread.IsAlive)
|
||||
Thread.SpinWait(500);
|
||||
threadComEvent.Close();
|
||||
|
||||
if (ipcClassNameMMA != null) ipcClassNameMMA.Dispose();
|
||||
if (ipcClassNameMMF != null) ipcClassNameMMF.Dispose();
|
||||
}
|
||||
|
||||
private static void createControlService()
|
||||
@ -233,5 +243,54 @@ namespace DS4Windows
|
||||
temp.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateIPCClassNameMMF(IntPtr hWnd)
|
||||
{
|
||||
if (ipcClassNameMMA != null) return; // Already holding a handle to MMF file. No need to re-write the data
|
||||
|
||||
try
|
||||
{
|
||||
StringBuilder wndClassNameStr = new StringBuilder(128);
|
||||
if (GetClassName(hWnd, wndClassNameStr, wndClassNameStr.Capacity) != 0 && wndClassNameStr.Length > 0)
|
||||
{
|
||||
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(wndClassNameStr.ToString());
|
||||
|
||||
ipcClassNameMMF = MemoryMappedFile.CreateNew("DS4Windows_IPCClassName.dat", 128);
|
||||
ipcClassNameMMA = ipcClassNameMMF.CreateViewAccessor(0, buffer.Length);
|
||||
ipcClassNameMMA.WriteArray(0, buffer, 0, buffer.Length);
|
||||
// The MMF file is alive as long this process holds the file handle open
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
/* Eat all exceptions because errors here are not fatal for DS4Win */
|
||||
}
|
||||
}
|
||||
|
||||
private static string ReadIPCClassNameMMF()
|
||||
{
|
||||
MemoryMappedFile mmf = null;
|
||||
MemoryMappedViewAccessor mma = null;
|
||||
|
||||
try
|
||||
{
|
||||
byte[] buffer = new byte[128];
|
||||
mmf = MemoryMappedFile.OpenExisting("DS4Windows_IPCClassName.dat");
|
||||
mma = mmf.CreateViewAccessor(0, 128);
|
||||
mma.ReadArray(0, buffer, 0, buffer.Length);
|
||||
return ASCIIEncoding.ASCII.GetString(buffer);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Eat all exceptions
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (mma != null) mma.Dispose();
|
||||
if (mmf != null) mmf.Dispose();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user