3

I'm an amateur at c# and I've been unable to locate the answer to this. Perhaps I am not aware of the correct terms to use.

When a video file is dragged onto my exe application, I would like the application to know that it was launched with a file and be able to know the path and filename of that file. This way, the user does not have to use the file>open menu.

Hope that makes sense. Thanks

Quantum_Kernel
  • 303
  • 1
  • 7
  • 19

3 Answers3

6

You can check the command line arguments which were used to launch the application. If your application was started by dropping a file on the .exe file, there will be a single command line argument with the path of the file.

string[] args = System.Environment.GetCommandLineArgs();
if(args.Length == 1)
{
    // make sure it is a file and not some other command-line argument
    if(System.IO.File.Exists(args[0])
    {
        string filePath = args[0];
        // open file etc.
    }
}

As your question title states, you want the path and the file name. You can get the file name using:

System.IO.Path.GetFileName(filePath); // returns file.ext
helb
  • 7,609
  • 8
  • 36
  • 58
  • 1
    or check the `string[] args` parameter to `Main`, which contains the same command-line args. – Ben Voigt Jan 17 '15 at 22:44
  • @BenVoigt Yeah, that would work too. I just remembered that you can get the cmdline args from anywhere in the code with above method, – helb Jan 17 '15 at 22:45
  • Yup your approach is more general, I just think it's worth mentioning both, so no one comes along and thinks they are different. – Ben Voigt Jan 17 '15 at 22:46
2

When you drag a file into a C# application, it will goes as an command-line argument to that application. Like console applications, you can catch it on the Main method on the Program class.

I'll explain it using Windows Forms application.

Open your Program class on the solution. Your program class should look like this.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

By default, when you create Windows Forms applications, they don't treat command line arguments. You have to make a tiny change on the signature of the Main method, so it can receive arguments:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

Now you can handle file name argument passed to the application. By default, Windows will put the file name as the first argument. Just do something like this:

    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        // Before Application.Run method, treat the argument passed.
        // I created an overload of the constructor of my Form1, so
        // it can receive the File Name and load the file on some TextBox.

        string fileName = null;

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

        Application.Run(new Form1(fileName));
    }

In case you want to know the constructor overload of my Form1, here it is. Hope it helps!

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    public Form1(string fileName) : this()
    {
        if (fileName == null)
            return;

        if (!File.Exists(fileName))
        {
            MessageBox.Show("Invalid file name.");
            return;
        }

        textBox1.Text = File.ReadAllText(fileName);
    }
}
Ismael
  • 622
  • 6
  • 11
  • All correct except the "you have to" part. In .NET, System.Environment gives access later (as helb's answer shows). In a generic Win32 program, the `GetCommandLine` API call does. There's no need to handle them specifically in Main, the argument is provided there to make it more convenient in case you do. – Ben Voigt Jan 17 '15 at 22:49
  • Thanks Ismael. This worked for me but I had to make one change because I was getting the text contents of the file, not its path+filename. textBox1.Text = File.ReadAllText(fileName); changed to textBox1.Text = fileName; – Quantum_Kernel Jan 17 '15 at 23:08
0

You need your application's command-line arguments. When you drop a file on your application in Explorer, Explorer opens the application with the file you dropped on it. You can select as many files as you want, drop them on your application and using this line of code, files will be an array of those command line arguments.

string[] files = Environment.GetCommandLineArgs();
zvava
  • 101
  • 1
  • 3
  • 14
Mustafa Chelik
  • 2,113
  • 2
  • 17
  • 29
  • Sorry, I didn't get what you were asking. So I edited my answer. – Mustafa Chelik Jan 17 '15 at 22:49
  • OK this worked for me also and is the simplest solution. Since it only returns a string variable and not a path, how can I extract only the filename from this? – Quantum_Kernel Jan 17 '15 at 23:21
  • It returns all files that you dropped on your application. `files` is an array of string. For example your first file is at `files[0]`. Is it what you are asking for? Or you want to get only filename without path? By the way, don't forget to upvote and accept the answer that was your answer. – Mustafa Chelik Jan 17 '15 at 23:28
  • If I load index 1 of that array into a string, it is the fill path+filename. How can I then also extract only the filename into another string? – Quantum_Kernel Jan 17 '15 at 23:31
  • Well, if you want to extract filename from a full path, you should code a little. This will work but you should check for errors and stuff: `string filename = files[0].Substring(files[0].LastIndexOf('\\') + 1);` – Mustafa Chelik Jan 17 '15 at 23:40