最近公司有個需求是,拖動文件到桌面圖標上,自動打開文件。那么只需在OnStartup事件中通過StartupEventArgs獲取文件名然后進行操作即可。操作之后發現當軟件已經啟動了(單例運行),那么將無法將參數傳給業務層。原因是因為跨進程了,那么我們可以通過窗口句柄的方式來進行通訊。
public partial class App : Application
{
private static Mutex AppMutex;
public App()
{
}
protected override void OnStartup(StartupEventArgs e)
{
var param = string.Empty;
if (e.Args.Length > 0)
{
param = e.Args[0].ToString();
}
AppMutex = new Mutex(true, "WpfApp8", out var createdNew);
if (!createdNew)
{
var current = Process.GetCurrentProcess();
foreach (var process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
Win32Helper.SetForegroundWindow(process.MainWindowHandle);
Win32Helper.SendMessageString(process.MainWindowHandle, param);
break;
}
}
Environment.Exit(0);
}
else
{
base.OnStartup(e);
}
}
}
public class Win32Helper
{
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
public const int WM_COPYDATA = 0x004A;
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
}
public static void SendMessageString(IntPtr hWnd, string message)
{
if (string.IsNullOrEmpty(message)) return;
byte[] messageBytes = Encoding.Unicode.GetBytes(message + '\0');
COPYDATASTRUCT cds = new COPYDATASTRUCT();
cds.dwData = IntPtr.Zero;
cds.cbData = messageBytes.Length;
cds.lpData = Marshal.AllocHGlobal(cds.cbData);
Marshal.Copy(messageBytes, 0, cds.lpData, cds.cbData);
try
{
SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
Marshal.FreeHGlobal(cds.lpData);
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
hwndSource.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_COPYDATA)
{
COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
string receivedMessage = Marshal.PtrToStringUni(cds.lpData);
Console.WriteLine("收到消息:" + receivedMessage);
MessageBox.Show(receivedMessage);
handled = true;
}
return IntPtr.Zero;
}
}

轉自https://www.cnblogs.com/wihalo/p/18293731
該文章在 2024/9/25 8:35:35 編輯過