Skip to content

Commit

Permalink
tweaks to handle unicode paths
Browse files Browse the repository at this point in the history
tweaks to handle unicode paths

.
  • Loading branch information
Beej126 committed Apr 12, 2024
1 parent ea4f7d9 commit 43c53e8
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
/bin
/obj
/.vs
/Properties/PublishProfiles/StandaloneExeToFolder.pubxml.user
/SingleInstanceAccumulator.csproj.user
31 changes: 9 additions & 22 deletions MessageForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public SingleInstanceMessageForm(string windowTitle, Action<string> onNewValue,
WindowState = FormWindowState.Minimized;
}

//private void Form1_Load(object sender, EventArgs e)
protected override void OnLoad(EventArgs e)
{
Win32.CHANGEFILTERSTRUCT changeFilter = new();
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down
4 changes: 4 additions & 0 deletions SingleInstanceAccumulator.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<RepositoryUrl>https://github.com/Beej126/SingleInstanceAccumulator</RepositoryUrl>
<PackageProjectUrl>https://github.com/Beej126/SingleInstanceAccumulator</PackageProjectUrl>
<AssemblyVersion>1.0.0.4</AssemblyVersion>
<FileVersion>1.0.0.4</FileVersion>
</PropertyGroup>
<ItemGroup>
<Compile Update="MessageForm.cs" />
Expand Down
17 changes: 0 additions & 17 deletions SingleInstanceAccumulator.csproj.user

This file was deleted.

37 changes: 21 additions & 16 deletions Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,31 @@ public abstract partial class Win32
/// </summary>
public static uint WM_COPYDATA = 0x004A;

/// <summary>
/// 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.
/// </summary>
public static uint WM_USER = 0x0400;

/// <summary>
/// Contains data to be passed to another application by the WM_COPYDATA message.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
/// <summary>
/// The data to be passed to the receiving application. This member can be IntPtr.Zero.
/// </summary>
public IntPtr dwData;

/// <summary>
/// The size, in bytes, of the data pointed to by the lpData member.
/// </summary>
public int cbData;

/// <summary>
/// The data to be passed to the receiving application. This member can be IntPtr.Zero.
/// </summary>
public IntPtr lpData;
/// <summary>
/// The data to be passed to the receiving application. This member can be IntPtr.Zero.
/// </summary>
public IntPtr dwData;

/// <summary>
/// The size, in bytes, of the data pointed to by the lpData member.
/// </summary>
public int cbData;

/// <summary>
/// The data to be passed to the receiving application. This member can be IntPtr.Zero.
/// </summary>
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string lpData;
}

/// <summary>
Expand All @@ -63,7 +68,7 @@ public struct COPYDATASTRUCT
/// <param name="lParam">Additional message-specific information.</param>
/// <returns>The return value specifies the result of the message processing; it depends on the message sent.</returns>
[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);

/// <summary>
/// Values used in the struct CHANGEFILTERSTRUCT
Expand Down

0 comments on commit 43c53e8

Please sign in to comment.