From 43c53e8d774578d22361a19c39328ef60717af19 Mon Sep 17 00:00:00 2001 From: Beej <6301228+Beej126@users.noreply.github.com> Date: Fri, 12 Apr 2024 16:09:34 -0700 Subject: [PATCH] tweaks to handle unicode paths tweaks to handle unicode paths . --- .gitignore | 2 ++ MessageForm.cs | 31 +++++++--------------- SingleInstanceAccumulator.csproj | 4 +++ SingleInstanceAccumulator.csproj.user | 17 ------------ Win32.cs | 37 +++++++++++++++------------ 5 files changed, 36 insertions(+), 55 deletions(-) delete mode 100644 SingleInstanceAccumulator.csproj.user diff --git a/.gitignore b/.gitignore index 7153f34..fb85032 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ /bin /obj /.vs +/Properties/PublishProfiles/StandaloneExeToFolder.pubxml.user +/SingleInstanceAccumulator.csproj.user diff --git a/MessageForm.cs b/MessageForm.cs index 67aa059..1a11a6f 100644 --- a/MessageForm.cs +++ b/MessageForm.cs @@ -24,7 +24,6 @@ public SingleInstanceMessageForm(string windowTitle, Action onNewValue, WindowState = FormWindowState.Minimized; } - //private void Form1_Load(object sender, EventArgs e) protected override void OnLoad(EventArgs e) { Win32.CHANGEFILTERSTRUCT changeFilter = new(); @@ -54,17 +53,15 @@ protected override void WndProc(ref Message m) { // Extract the file name Win32.COPYDATASTRUCT copyData = (Win32.COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(Win32.COPYDATASTRUCT)); - int dataType = (int)copyData.dwData; - if (dataType == 2) + if (copyData.dwData == (Win32.WM_USER + 1)) { - string fileName = Marshal.PtrToStringAnsi(copyData.lpData); Timer.Interval = TimeoutMillisecs; //this is a timer "reset" - OnNewValue(fileName); + OnNewValue(copyData.lpData); //MessageBox.Show($"received: {fileName}", "SingleInstanceArgAggregator", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { - MessageBox.Show(String.Format("Unrecognized data type = {0}.", dataType), "SingleInstanceArgAggregator", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show($"Unrecognized message id, expecting {Win32.WM_USER + 1}, got {copyData.dwData}."); } } else @@ -87,39 +84,29 @@ public static bool SendStringToWindow(string windowTitle, string data) if (retries == 0) { - MessageBox.Show($"Couldn't find window named: {windowTitle}", "SingleInstanceArgAggregator", MessageBoxButtons.OK, MessageBoxIcon.Error); + MessageBox.Show($"Couldn't find window named: {windowTitle}"); return false; } - var ptrCopyData = IntPtr.Zero; + //good example of COPYDATA + SendMessage: https://forum.strokesplus.net/posts/t6052-Using-Windows-Messages--WM-COPYDATA--to-Execute-Scripts try { // Create the data structure and fill with data Win32.COPYDATASTRUCT copyData = new Win32.COPYDATASTRUCT { - dwData = new IntPtr(2), // Just a number to identify the data type - cbData = data.Length + 1, // One extra byte for the \0 character - lpData = Marshal.StringToHGlobalAnsi(data) + dwData = new IntPtr(Win32.WM_USER + 1), // Just an arbitrary number to make sure we're getting our specific message on the other side + cbData = System.Text.Encoding.Unicode.GetBytes(data).Length + 1, // One extra byte for the \0 character + lpData = data }; - // Allocate memory for the data and copy - ptrCopyData = Marshal.AllocCoTaskMem(Marshal.SizeOf(copyData)); - Marshal.StructureToPtr(copyData, ptrCopyData, false); - // Send the message - Win32.SendMessage(ptrWnd, Win32.WM_COPYDATA, IntPtr.Zero, ptrCopyData); + Win32.SendMessage(ptrWnd, Win32.WM_COPYDATA, IntPtr.Zero, ref copyData); } catch (Exception ex) { MessageBox.Show(ex.ToString(), windowTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } - finally - { - // Free the allocated memory after the contol has been returned - if (ptrCopyData != IntPtr.Zero) - Marshal.FreeCoTaskMem(ptrCopyData); - } return true; diff --git a/SingleInstanceAccumulator.csproj b/SingleInstanceAccumulator.csproj index e84de64..bbbdea6 100644 --- a/SingleInstanceAccumulator.csproj +++ b/SingleInstanceAccumulator.csproj @@ -6,6 +6,10 @@ enable true enable + https://github.com/Beej126/SingleInstanceAccumulator + https://github.com/Beej126/SingleInstanceAccumulator + 1.0.0.4 + 1.0.0.4 diff --git a/SingleInstanceAccumulator.csproj.user b/SingleInstanceAccumulator.csproj.user deleted file mode 100644 index 8b1fb88..0000000 --- a/SingleInstanceAccumulator.csproj.user +++ /dev/null @@ -1,17 +0,0 @@ - - - - -f -v "-c:powershell -ExecutionPolicy bypass c:\bin\test.ps1 -list %24files" "this is file1 path" - - - -v "-c:powershell -ExecutionPolicy bypass c:\bin\test.ps1 -list %24files" "this is file1 path" - - - <_LastSelectedProfileId>C:\save\repos\Personal\SingleInstanceAccumulator\Properties\PublishProfiles\FolderProfile.pubxml - - - - Form - - - \ No newline at end of file diff --git a/Win32.cs b/Win32.cs index 9d8e363..c08dd21 100644 --- a/Win32.cs +++ b/Win32.cs @@ -32,26 +32,31 @@ public abstract partial class Win32 /// public static uint WM_COPYDATA = 0x004A; + /// + /// The WM_USER constant is used by applications to help define private messages for use by private window classes, usually of the form WM_USER+X, where X is an integer value. + /// + public static uint WM_USER = 0x0400; + /// /// Contains data to be passed to another application by the WM_COPYDATA message. /// - [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { - /// - /// The data to be passed to the receiving application. This member can be IntPtr.Zero. - /// - public IntPtr dwData; - - /// - /// The size, in bytes, of the data pointed to by the lpData member. - /// - public int cbData; - - /// - /// The data to be passed to the receiving application. This member can be IntPtr.Zero. - /// - public IntPtr lpData; + /// + /// The data to be passed to the receiving application. This member can be IntPtr.Zero. + /// + public IntPtr dwData; + + /// + /// The size, in bytes, of the data pointed to by the lpData member. + /// + public int cbData; + + /// + /// The data to be passed to the receiving application. This member can be IntPtr.Zero. + /// + [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] + public string lpData; } /// @@ -63,7 +68,7 @@ public struct COPYDATASTRUCT /// Additional message-specific information. /// The return value specifies the result of the message processing; it depends on the message sent. [DllImport("user32.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); + public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); /// /// Values used in the struct CHANGEFILTERSTRUCT