WPF: Setting source to Browser control prevents application from recieveing the arguments.

On setting source in WebBrowserControl , the app stops receiving arguments passed from command line.
Usage:
- run the exe from commandline : BrowserArgsIgnore.exe
- Minimize the window
- try passing a arguments again with BrowserArgsIgnore.exe "Testing"
Please find the code below. I have also attached zip.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Text;
namespace BrowserArgsIgnore
{
internal static class UnsafeNative
{
public const int WM_COPYDATA = 0x004A;
public static string GetMessage(int message, IntPtr lParam)
{
if (message == UnsafeNative.WM_COPYDATA)
{
try
{
var data = Marshal.PtrToStructure<UnsafeNative.COPYDATASTRUCT>(lParam);
var result = string.Copy(data.lpData);
return result;
}
catch
{
return null;
}
}
return null;
}
public static void SendMessage(IntPtr hwnd, string message)
{
var messageBytes = Encoding.Unicode.GetBytes(message); /* ANSII encoding */
var data = new UnsafeNative.COPYDATASTRUCT
{
dwData = IntPtr.Zero,
lpData = message,
cbData = messageBytes.Length + 1 /* +1 because of \0 string termination */
};
if (UnsafeNative.SendMessage(hwnd, WM_COPYDATA, IntPtr.Zero, ref data) != 0)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
[StructLayout(LayoutKind.Sequential)]
private struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPWStr)]
public string lpData;
}
}
}
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace BrowserArgsIgnore
{
public static class Program
{
/// <summary>
/// Main
/// </summary>
/// <param name="args"></param>
[STAThread]
public static void Main(string[] args)
{
var proc = Process.GetCurrentProcess();
var processName = proc.ProcessName.Replace(".vshost", "");
var runningProcess = Process.GetProcesses()
.FirstOrDefault(x => (x.ProcessName == processName || x.ProcessName == proc.ProcessName || x.ProcessName == proc.ProcessName + ".vshost") && x.Id != proc.Id);
if (runningProcess == null)
{
var app = new App();
var window = new MainWindow();
MainWindow.HandleParameter(args);
app.Run(window);
return; // In this case we just proceed on loading the program
}
if (args.Length > 0)
UnsafeNative.SendMessage(runningProcess.MainWindowHandle, string.Join(" ", args));
}
}
<Application x:Class="BrowserArgsIgnore.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BrowserArgsIgnore">
<Application.Resources>
</Application.Resources>
</Application>
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
<Window x:Class="BrowserArgsIgnore.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BrowserArgsIgnore"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock x:Name="textBlock" Text="Try minimize the window & pass arguments from commandline" />
<WebBrowser Grid.Row="1" Source="https://www.google.com">
</WebBrowser>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BrowserArgsIgnore
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += (s, e) =>
{
MainWindow.WindowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;
HwndSource.FromHwnd(MainWindow.WindowHandle)?.AddHook(new HwndSourceHook(HandleMessages));
};
}
public static IntPtr WindowHandle { get; private set; }
private static IntPtr HandleMessages(IntPtr handle, int message, IntPtr wParameter, IntPtr lParameter, ref Boolean handled)
{
if (handle != MainWindow.WindowHandle)
return IntPtr.Zero;
var data = UnsafeNative.GetMessage(message, lParameter);
if (data != null)
{
if (Application.Current.MainWindow == null)
return IntPtr.Zero;
if (Application.Current.MainWindow.WindowState == WindowState.Minimized)
Application.Current.MainWindow.WindowState = WindowState.Normal;
UnsafeNative.SetForegroundWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);
var args = data.Split(' ');
HandleParameter(args);
handled = true;
}
return IntPtr.Zero;
}
public static void HandleParameter(string[] args)
{
if (Application.Current?.MainWindow is MainWindow mainWindow)
{
if (args != null && args.Length > 0)
{
mainWindow.textBlock.Text = $"Article Id: {args[0]}";
}
else
{
// mainWindow.textBlock.Text = "Trying:" + string.Join("\r\n", args);
if (args.Length > 0)
{
mainWindow.textBlock.Text = $"Article Id: {args[0]}";
//mainWindow.WebBrowserControl.Navigate(new Uri(link, UriKind.RelativeOrAbsolute));
//mainWindow.Back.IsEnabled = mainWindow.WebBrowserControl.CanGoBack;
}
}
}
}
}
}
Hi DaisyTian-MSFT.
Thank you for your response. Yes I did receive argument on normal/maximized state.
I gave a try once again, I came to understand that irrespective of the framework version, it did work on one system and failed in another.
Do you think it is because of the IE version (being used) or some registry entries which corresponds to the system?
@Anudeep Garge
WebBrowser runs depending on the version of IE, are the versions of IE that run successfully the same as on that fail?