Diskuze: Načtení asociovaného souboru
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.


Ještě raději dodám, že mám takto bráním spuštění další instance aplikace:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
static Mutex mutex = new Mutex(false, "Prohlížeč 3.0");
[STAThread]
static void Main()
{
if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
{
return;
}
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
}
}
nijak, prostě se spustí ta přiřazená aplikace (popř tu co vybere uživatel v dialogu Otevřít v aplikaci), tak že ti ten soubor předají v parametrech příkazového řádku no a takto nově spuštěná aplikace si to nějak vykomunikuje s již otevřenou aplikací.
i když nevím jestli ti to nějak půjde tím že ti to zablokuje ten mutex, ale snad jo.
jt.e:23.2.2016 21:52
Chápu, ale jak ty parametry předat spuštěné aplikaci?
Michal Žůrek - misaz:23.2.2016 22:05
operační systém ti předá jako parametr příkazového řádku cestu k souboru na který uživatel poklikal.
Nějak mi to funguje
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace textshow
{
static class Program
{
public const int WM_COPYDATA = 0x004A;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32.dll", EntryPoint = "FindWindow")]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
IntPtr h = FindWindowByCaption(IntPtr.Zero, "Prohlížeč 3.0");
if (IntPtr.Zero == h)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length > 1)
{
SendParam(h, arguments[1]);
}
}
}
public static IntPtr IntPtrAlloc<T>(T param)
{
IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param));
Marshal.StructureToPtr(param, retval, false);
return retval;
}
// Free a pointer to an arbitrary structure from the global heap.
public static void IntPtrFree(ref IntPtr preAllocated)
{
if (IntPtr.Zero == preAllocated)throw (new NullReferenceException("Zero == preAllocated"));
Marshal.FreeHGlobal(preAllocated);
preAllocated = IntPtr.Zero;
}
public static void SendParam(IntPtr hWnd, string message)
{
try
{
COPYDATASTRUCT cds;
cds.dwData = IntPtr.Zero;
cds.cbData = 2 * (message.Length + 1); // TADY NEVÍM
cds.lpData = Marshal.StringToHGlobalAuto(message.ToString());
IntPtr cdsBuffer = IntPtrAlloc(cds);
SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, cdsBuffer);
IntPtrFree(ref cds.lpData);
IntPtrFree(ref cdsBuffer);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
ve Form1.cs
protected override void WndProc(ref Message m)
{
if(m.Msg == Program.WM_COPYDATA)
{
try
{
COPYDATASTRUCT cds;
cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
string arg = Marshal.PtrToStringAuto(cds.lpData);
LoadFromFile(arg);
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
}
base.WndProc(ref m);
}
Je pořád nemůžu přijít nato jak správně zaznamenat velikost
objektu:
cds.cbData = 2 * (message.Length + 1); myslím nebude úplně
správně
a můžete mi prosím říct co ještě mám nesprávně?
Oprava: Jen pořád nemůžu přijít na to, jak správně zaznamenat..
A prosím, kdyby mi někdo vysvětlil funkce IntPtrAlloc a IntPtrFree, ty mám z netu a moc nechápu co přesně dělají (Je mi pouze jasné že slouží k alokaci a uvolnění), ale jak přesně fungují a proč tam musí být...?
Takže asi hotovo.
//Program.cs
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace textshow
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main()
{
IntPtr h = Native.FindWindowByCaption(IntPtr.Zero, "Prohlížeč 3.0");
if (IntPtr.Zero == h)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length > 1)
{
SendParam(h, arguments[1]);
}
}
}
public static void SendParam(IntPtr hWnd, string message)
{
try
{
COPYDATASTRUCT cds;
cds.dwData = 2016;
cds.cbData = 0;
cds.lpData = message;
IntPtr strprt = Marshal.AllocHGlobal(Marshal.SizeOf(cds)); ;
Marshal.StructureToPtr(cds, strprt, false);
Native.SendMessage(hWnd, Native.WM_COPYDATA, IntPtr.Zero, strprt);
Native.IntPtrFree(ref strprt);
Native.SetForegroundWindow(hWnd);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
//-------------------------------------------------------------------------
public struct COPYDATASTRUCT
{
public int cbData;
public int dwData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
//-------------------------------------------------------------------------
public static class Native
{
public const int WM_COPYDATA = 0x004A;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public static void IntPtrFree(ref IntPtr preAllocated)
{
if (IntPtr.Zero == preAllocated) return;
Marshal.FreeHGlobal(preAllocated);
preAllocated = IntPtr.Zero;
}
}
//-------------------------------------------------------------------------
}
//============================================
//Form1.cs
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;
namespace textshow
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void LoadFromFile(string filename)
{
try
{
using (StreamReader r = new StreamReader(filename, Encoding.Default, true))
{
textBox1.Clear();
textBox1.Text = r.ReadToEnd();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void LoadParams()
{
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length > 1)
{
if (File.Exists(arguments[1])) LoadFromFile(arguments[1]);
}
}
private void Form1_Shown(object sender, EventArgs e)
{
LoadParams();
}
protected override void WndProc(ref Message m)
{
if(m.Msg == Native.WM_COPYDATA)
{
try
{
COPYDATASTRUCT cds;
cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT));
if (cds.dwData == 2016)
{
LoadFromFile(cds.lpData);
}
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
}
base.WndProc(ref m);
}
}
}
+5 Zkušeností

sadlomaslox25:25.2.2016 20:27
podle me to mas nejaky slozity. ja bych osobne pouzij asi jen
[STAThread]
static void Main(string[] args)
{
try
{
NamedPipeServerStream server = new NamedPipeServerStream("myServer") ;
Task.Factory.StartNew(() =>
{
var stream = new StreamReader(server);
while (true)
{
server.WaitForConnection();
var filePath = stream.ReadLine();
server.Disconnect();
MessageBox.Show($"File: {filePath}", "Title", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
}
});
}
catch (Exception ex)
{
using (var client = new NamedPipeClientStream("myServer"))
using (var stream = new StreamWriter(client))
{
client.Connect(3000);
stream.AutoFlush = true;
stream.WriteLine(args?.FirstOrDefault() ?? "none");
}
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
jt.e:25.2.2016 21:51
A jak v tomto způsobu předám spuštěné aplikaci argumenty a spustím funkci LoadFromFile ? Mohl bych prosit o ukázku na daném projektu?
sadlomaslox25:25.2.2016 23:19
public partial class Form1 : Form
{
public Form1(string filename)
{
InitializeComponent();
LoadFromFile(filename);
}
public void LoadFromFile(string filename)
{
if (!File.Exists(filename))
{
textBox1.Clear();
MessageBox.Show("File not exists");
return;
}
try
{
using (StreamReader r = new StreamReader(filename, Encoding.Default, true))
{
textBox1.Clear();
textBox1.Text = r.ReadToEnd();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
[STAThread]
static void Main(string[] args)
{
Form1 form = null;
try
{
NamedPipeServerStream server = new NamedPipeServerStream("myServer");
Task.Factory.StartNew(() =>
{
var stream = new StreamReader(server);
while (true)
{
server.WaitForConnection();
var filePath = stream.ReadLine();
server.Disconnect();
form.Invoke(new Action(() => form.LoadFromFile(filePath)));
}
});
}
catch (Exception ex)
{
using (var client = new NamedPipeClientStream("myServer"))
using (var stream = new StreamWriter(client))
{
client.Connect(3000);
stream.AutoFlush = true;
stream.WriteLine(args?.FirstOrDefault() ?? "");
}
return;
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(form = new Form1(args?.FirstOrDefault()));
}
}
Zobrazeno 18 zpráv z 18.