MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Вывод путей нескольких выделенных файлов в проводнике через программу C#"
Answer 937988
Когда пользователь открывает в проводнике несколько файлов, проводник создает несколько процессов примерно в один момент времени. Однако, от старта процесса до момента, когда окно будет готово к приему сообщений, проходит некоторое время. Поэтому нужно несколько модифицировать способ с WM_COPYDATA, чтобы он смог обработать эту ситуацию: добавить ожидание создания окна в основном процессе, избегать использования MessageBox, так как он блокирует выполнение, и т.д.
Класс Application:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows; using System.Runtime.InteropServices; using System.Diagnostics; namespace WpfApp1 { public partial class App : Application { [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; public IntPtr lpData; } public const uint WM_COPYDATA = 0x004A; private void Application_Startup(object sender, StartupEventArgs e) { string command = ""; string[] argv = Environment.GetCommandLineArgs(); if (argv.Length > 1) command = argv[1]; Process this_process = Process.GetCurrentProcess(); Process main_process; //найти все процессы с таким же именем, запущенные ранее данного процесса Process[] other_processes = Process.GetProcessesByName(this_process.ProcessName) .Where(pr => { return pr.Id != this_process.Id && pr.StartTime <= this_process.StartTime;}) .OrderBy((pr) => { return pr.StartTime; }) .ToArray(); //найти основной процесс if (other_processes.Length > 0) main_process = other_processes[0]; else return; //ждем создания окна в основном процессе IntPtr hWnd; int c = 0; while (true) { hWnd = main_process.MainWindowHandle; if (hWnd != IntPtr.Zero) break; System.Threading.Thread.Sleep(100); c++; if (c > 10) { return; } } //отправляем команду var cds = new COPYDATASTRUCT(); cds.dwData = (IntPtr)1; cds.cbData = (command.Length + 1) * 2; cds.lpData = Marshal.StringToHGlobalUni(command); SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds); Marshal.FreeHGlobal(cds.lpData); //завершаем работу Environment.Exit(0); } } }
MainWindow.xaml:
<Window x:Class="WpfApp1.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" mc:Ignorable="d" Title="MainWindow" Height="400" Width="600" Loaded="Window_Loaded"> <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > <TextBox HorizontalAlignment="Left" Height="210" Margin="10,46,0,0" x:Name="tbFilename" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="427"/> </Grid> </Window>
MainWindow.xaml.cs
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Runtime.InteropServices; using System.Windows.Interop; namespace WpfApp1 { public partial class MainWindow : Window { //обработчик сообщений для окна private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == App.WM_COPYDATA) { App.COPYDATASTRUCT data = new App.COPYDATASTRUCT(); data = (App.COPYDATASTRUCT)Marshal.PtrToStructure(lParam, data.GetType()); tbFilename.Text += Marshal.PtrToStringUni(data.lpData)+";"; } return IntPtr.Zero; } public MainWindow() { InitializeComponent(); string[] argv = Environment.GetCommandLineArgs(); if (argv.Length > 1) tbFilename.Text += argv[1] + ";"; } private void Window_Loaded(object sender, RoutedEventArgs e) { WindowInteropHelper h = new WindowInteropHelper(this); HwndSource source = HwndSource.FromHwnd(h.Handle); source.AddHook(new HwndSourceHook(WndProc));//регистрируем обработчик сообщений } } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.