C# wpf open serialized file with windows - c#

I've a custom file. Serialization and deserialization is working
fine when using my custom functions
File > Save
File > Open
When I'm going directly in the windows explorer on my file
and want to open it with the program it's not deserializing.
How can I handle the deserialization from "outside"?
Thanks for your help.

When a file is opened from Windows Explorer with your app, the absolute path of the file is passed as the first command line argument.
In case of WPF, you can handle the Startup event of App to intercept such an argument for later opening in MainWindow.
// App.xaml.cs
public string FileToOpen;
public App()
{
Startup += (sender, e) =>
{
if (e.Args.Length > 0)
FileToOpen = e.Args[0];
};
}
// MainWindow.xaml.cs
public MainWindow()
{
var path = (Application.Current as App).FileToOpen;
if (path != null)
{
// TODO: open the file when appropriate
}
}

Related

get the file location when open applicaiton

I created an WPF application the use a viewer for file I set the application as default application for this application (filename.myapp), now if I try to open the file it will start the application but I need to know how to get this file location and name so I can use it in the application.
If I understood your question correctly you want to know the name of the file that was double-clicked/opened with your application associated.
It is the second item in the args array of your start up event:
private void Application_Startup(object sender, StartupEventArgs e)
{
...
if(e.Args.Length > 1)
{
var filename = e.Args[1]);
}
...
}
This is how I did it in the end:
var args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
var fileName= args[1];
}

How to open a file with an executable already open?

i have a C#/WPF project that represents a dbf editor that allows you to open files in 3 ways:
- with apposit button in toolbar
- with drag & drop
- with double click on file
Now i use a TabControl that contain every dbf open.
I can handle it with my internal button and drag add item to container.
if I open a file with the double click and there is an open instance I would like to add it to the container and instead open a new instance.
My code :
App
public partial class App : Application
{
private static Editor mainWindow = null;
protected override void OnStartup(StartupEventArgs e)
{
Editor mainWindow = new Editor(e.Args);
mainWindow.Show();
}
}
Editor:
public partial class Editor : Window
{
ChooseMessage.Choose choose;
public Dictionary<int, DBFStructure> ds;
string DbfName;
private string[] OldNew;
public Editor(string[] e)
{
InitializeComponent();
ds = new Dictionary<int, DBFStructure>();
OldNew = new string[2];
choose = ChooseMessage.Choose.OK;
if (e.Length > 0)
if (File.Exists(e[0]) && e[0].EndsWith(".dbf", StringComparison.InvariantCultureIgnoreCase))
EffOpen(e[0]);
}
private void dbf_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop, true) == true)
{
string filename = ((string[])e.Data.GetData(DataFormats.FileDrop, true))[0];
if (File.Exists(filename) && filename.EndsWith(".dbf", StringComparison.InvariantCultureIgnoreCase))
EffOpen(filename);
}
}
....
}
I apologize for code display but I can not set it correctly.
my problem is to intercept the opening of a dbf from the last open editor instance and add it to the controltab, otherwise create a new instance.
P.S. EffOpen(filename) represents the method that, by passing the fil name, loads it and adds it to the container
Thanks to all
When you open a file with a double click, a new application instance will be started by Windows. This is by design, you cannot change this.
In this new instance you have no direct references to the objects of your first application instance, so you cannot just add the file being opened to the TabControl of the first instance.
You need to implement it like that:
since you can open files via double click, your application can handle files using the command line arguments - that's good
you need a way to check whether there is an instance already running - use a Mutex with a dedicated and unique name to do that; try creating a Mutex on app startup and check the out parameter of the Mutex(bool, string, out bool) constructor - if it's false, then there is an instance already
you need a way to tell the already running instance that it needs to open a file that has been passed as the command line argument to the second instance; use any of the inter-proc methods that better suits you: a NamedPipe would be a pretty simple way

WPF How to get second clicked file path for Single Instance App

I created my WPF single instance app by using the Microsoft.VisualBasic dll method. However I'm facing some difficulty to get the file path for second clicked file which associated with my app.
For example, I have two file "First.my" and "Second.my". When I click on file "First.my" it will launch my app and pop up message box to show "First.my" file path. Since my app is single instance app, when I click on file "Second.my" it should show the file path for "Second.my" but it still showing the file path for "First.my"..
Does anyone know how to pass the associate file path in single instance app?
Below is my code:
class WindowsFormsApp : Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase
{
private App _wpfApp;
public WindowsFormsApp()
{
IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
MessageBox.Show("First File");
//Get 1st click file path
GetFilePath();
_wpfApp = new App();
_wpfApp.Run();
return false;
}
protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
{
MessageBox.Show("Second File");
//Get 2nd click file path
GetFilePath();
}
protected void GetFilePath()
{
if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null &&
AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > 0)
{
var filePath = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
var uri = new Uri(filePath);
MessageBox.Show(uri.LocalPath);
}
}
}

Placing a link in windows 8 metro style app

How can I link my web address www.facebook.com to my hyperlink button.and that should load in my app page.
You can only load a web page inside a WebView control. Put it somewhere on your page first:
<WebView x:Name="MyWebView" />
In the click event handler of your Hyperlink load the page into this WebView:
private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
{
MyWebView.Navigate(new Uri("http://www.facebook.com"));
}
Process.Start("http://facebook.com"); that will load the default browser at facebook.com is this what you require ?
how about the launcher class ? You can use the Launcher class to launch a document in the default handler, i.e load a website with the default browser, from what i understand you cant just create a process.
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string imageFile = #"images\test.png";
var file = wait Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
if (file != null)
{
// Launch the retrieved file
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
}

c# - WPF command-line argument for opening file gives infinite loop

This is a weird one! I am working on an application that reads vCard files, which contain contact etc. information for a person. Each file may contain separate 'sections' that each contain the details for one person, which are separated by BEGIN:VCARD [data here] END:VCARD.
To enable my users to view all of the different details, I've allowed my program to populate the textboxes in my app with the details and then open a new Window and do this with that one, but for each of the different sections in the file.
The problem comes about when my program opens when a vCard file has been double clicked in Explorer. It keeps looping through the vCard. I don't know what to do, but below is my problematic code:
public void readVcard(string fname)//Reads vCard and then loops through sections
{
try
{
using (StreamReader r = new StreamReader(fname))
{
string input = File.ReadAllText(fname);//read through file
String[] vArray = input.Split(new string[] { "BEGIN:VCARD" }, StringSplitOptions.None);
int i;
for (i = 1; i < vArray.Length; i++)
{
MainWindow a = new MainWindow();
a.parser(vArray[i]); //Parser is the function that populates the app
a.Show();
}
return;
}
}...
This function is called from here:
void MainWindow_Loaded(object sender, RoutedEventArgs e)//Processes a file when opened externally
{
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
readVcard(fname);
}
}
If anyone could help, it would be greatly appreciated.
I think that Artyom is on the right track.
Every time you create another MainWindow and load it you will be getting the current applications argurment and jumping back in to readVcard, which will process the same vCard that you are already processing and open yet another MainWindow which will continue the process.
Consider moving all of the code you have inside of MainWindow_Loaded() to the Startup event for your application. That way it will only get called once when your program first loads, instead of every time you create a new window.
To do this you need to register for the event in your App.xaml file like so:
<Application x:Class="MyProgram.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="Application_Startup">
</Application>
And then in the code behind App.xaml you put your code for reading the vCard. Like this:
namespace MyProgram
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
readVcard(fname);
}
}
}
}
When you create and show new MainWindow (a.Show()), the MainWindow_Loaded event fires again and it again calls a readVcard method. So there is an infinite loop.
Or may be not really infinite, because, I belive, some time later a StackOverflowException may happen.
You just need to review startup logic, so readVcard will launch not in the MainWindow_Loaded event, but, for example, in the Main method (in program.cs file). Or you may add some flag, which will be set when readVcard method first called.
I get it! I've now got the following code in App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (e.Args != null && e.Args.Count() > 0)
{
this.Properties["ArbitraryArgName"] = e.Args[0];
}
base.OnStartup(e);
if (Application.Current.Properties["ArbitraryArgName"] != null)
{
string fname = Application.Current.Properties["ArbitraryArgName"].ToString();
MainWindow mw = new MainWindow();
mw.readVcard(fname);
}
}
}
It works fine! Thanks everyone. BTW the following blog contains the command-line info I originally used if anyone needs it: http://blogs.msdn.com/b/avip/archive/2008/10/27/wpf-supporting-command-line-arguments-and-file-extensions.aspx.

Categories

Resources