Make my application default to open all .txt files

After publishing my application, I can assign the default exe file of my application to open .txt files. Here, how can I get the filePath for the file that called the application?

    public MainWindow()
    {
        InitializeComponent();
        string filePath = "";
        FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        StreamReader sr = new StreamReader(fs);
        txt.Text = sr.ReadToEnd();
        sr.Close();
        fs.Close();
    }

      

Here, how can I get the filePath when the user double-clicks on some txt file from explorer ..?

+3


source to share


5 answers


There are two ways to get command line arguments in .NET. You can put the parameter list in your method Main

, or you can use the method Environment.GetCommandLineArgs

.

var allArgs = Environment.GetCommandLineArgs();
// The first element is the path to the EXE. Skip over it to get the actual arguments.
var userSpecifiedArguments = allArgs.Skip(1);

      



Since you are using WPF (and therefore have no control over the method Main

), your best bet is to go with GetCommandLineArgs

.

+1


source


File arguments are passed through command line arguments. So you need to check the file Program.cs

(maybe) to look at the parameter string[] args

.

void Main(string[] args)
{
    string filename;

    if(args != null && args.Length > 0)
        filename = args[0];
    else
        filename = null;

    // use filename as appropriate, perhaps via passing it to your entry Form.
}

      

Basically, the call that explorer.exe

(Windows Explorer, Desktop, Start Menu, what you have) makes when you double-click test.txt

when Notepad is the default text editor is something like / p>

notepad.exe C:\users\name\desktop\test.txt

      



This is the same syntax you would use on the command line to invoke robocopy

(although you will probably need more arguments than this):

robocopy source.txt destination.txt

      

As a result of this workflow, you can also override the default file association behavior to launch a program of your choice to read the file, similar to the program Open With...

. The following will always open Notepad, no matter what other application the extension might be associated with .jpg

(which is probably not an entry).

notepad.exe C:\users\name\desktop\test.jpg

      

+2


source


There are several ways to make your application the default application for a particular file type.

  • You can manually change the registry value and specify the application path for the .txt extension. HKEY_CURRENT_USER \ Software \ Classes
  • Assign properties in the setup project: Project Properties-> Publish-> Options-> File Assortment → [Add Extensions]
  • You can write code to modify the registry and link the default application for a specific extension.

[DllImport("Kernel32.dll")]
private static extern uint GetShortPathName(string lpszLongPath, 
    [Out] StringBuilder lpszShortPath, uint cchBuffer);

// Return short path format of a file name
private static string ToShortPathName(string longName)
{
    StringBuilder s = new StringBuilder(1000);
    uint iSize = (uint)s.Capacity;
    uint iRet = GetShortPathName(longName, s, iSize);
    return s.ToString();
}

// Associate file extension with progID, description, icon and application
public static void Associate(string extension, 
       string progID, string description, string icon, string application)
{
    Registry.ClassesRoot.CreateSubKey(extension).SetValue("", progID);
    if (progID != null && progID.Length > 0)
        using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(progID))
        {
            if (description != null)
                key.SetValue("", description);
            if (icon != null)
                key.CreateSubKey("DefaultIcon").SetValue("", ToShortPathName(icon));
            if (application != null)
                key.CreateSubKey(@"Shell\Open\Command").SetValue("", 
                            ToShortPathName(application) + " \"%1\"");
        }
}

// Return true if extension already associated in registry
public static bool IsAssociated(string extension)
{
    return (Registry.ClassesRoot.OpenSubKey(extension, false) != null);
}

///How to Associate
///.ext: give the extension here ie. .txt
///ClassID.ProgID: Give the unique id for your application. ie. MyFirstApplication1001
///ext File:Description of your application
///YourIcon.ico:Icon file
///YourApplication.exe:Your application name
Associate(".ext", "ClassID.ProgID", "ext File", "YourIcon.ico", "YourApplication.exe");

      

You can also read this article and download an example for it from here

+1


source


With the help of Matthew Haugen I did this and his work on the Forms Application

Program.cs

static class Program
{
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1(args != null && args.Length > 0 ? args[0] : ""));
    }
}

      

And the shape

public partial class Form1 : Form
{
    public Form1(string fileName)
    {
        InitializeComponent();
        if (fileName != "")
            using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            using (var sr = new StreamReader(fs)) textBox1.Text = sr.ReadToEnd();
    }
}

      

I suppose this might help some for Forms Application. But I am still looking for an answer for doing the same in WPF.

0


source


Here's a solution for WPF

Matthew showed me how to do this in a Windows Forms application and did a little research and found a solution for wpf.

Here's a step by step I've done.

First I added the main void function to App.Xaml.cs

 public partial class App : Application
{
    [STAThread]

    public static void Main()
    {

    }
}

      

It showed an error when compiling. Providing multiple entry points for the application. When double clicked, it moves to the App.g.cs file where the actual entry point exists.

   public partial class App : System.Windows.Application {

    /// <summary>
    /// InitializeComponent
    /// </summary>
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    public void InitializeComponent() {

        #line 4 "..\..\App.xaml"
        this.StartupUri = new System.Uri("MainWindow.xaml", System.UriKind.Relative);

        #line default
        #line hidden
    }

    /// <summary>
    /// Application Entry Point.
    /// </summary>
    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    public static void Main() {
        FileOpen.App app = new FileOpen.App();
        app.InitializeComponent();
        app.Run();
    }
}

      

...

Now I removed all lines and copied the entry point to App.xaml.cs And also removed the startupURI from App.xaml

<Application x:Class="FileOpen.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         >
<Application.Resources>

</Application.Resources>

      

Now App.g.cs

public partial class App : System.Windows.Application {

    /// <summary>
    /// Application Entry Point.

}

      

And app.xaml.cs

public partial class App : Application
{
    [System.STAThreadAttribute()]
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    public static void Main(string[] args)
    {
        MainWindow window = new MainWindow(args != null && args.Length > 0 ? args[0] : "");
        window.ShowDialog();
    }
}

      

And MainWindow

public partial class MainWindow : Window
{
    public MainWindow(string filePath)
    {
        InitializeComponent();
        if (filePath != "")
            using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            using (var sr = new StreamReader(fs)) txt.Text = sr.ReadToEnd();
    }
}

      

0


source







All Articles