Shashank Jain
Shashank Jain

Reputation: 101

How to make a openfile dialog box in console application .NET Core (C#)?

I want to give an option of selecting the files from anywhere in the pc. Currently I am giving the path explicitly like this:

FileInfo existingFile = new FileInfo(@"C:\Users\User_name\Downloads\bank_statement.xlsx");

Using EPPlus to manipulate excel files. How to get files directly from the desired folder? Console application .NET Core 3.1 C#.

Upvotes: 5

Views: 14505

Answers (3)

MikeF
MikeF

Reputation: 1018

The STAThread attribute on main did not work for me. Creating a new thread from this answer did.

class Program
{

public static async Task Main(string[] args)
{
    
    Console.WriteLine("Hello World!");
    string path = await GetFile(); 
    Console.WriteLine("Found Path: "+path);

}

private static async Task<string> GetFile()
{
    Thread thread = new Thread(OpenDialogue);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join(); 
    return path;
}

private static void OpenDialogue(object? obj)
{
    OpenFileDialog dialog = new OpenFileDialog();
    if (DialogResult.OK == dialog.ShowDialog())
    {
        path = dialog.FileName;
    }
    else
    { 
        path = "Cancelled";
    }
}

private static string path= "Not INitialized";

}

Still working through what everything does. The async Task<string> GetFile just creates the thread. Probably does not need to be async unless actually loading and returning a large file instead of just the string path. I have not worked through how to use the object? obj. Will come back and update if I get there.

Upvotes: 0

Victor
Victor

Reputation: 8935

If it's really necessary to use .NET GUI components in the console application you should convert it to the UI application. But after that the application is become to GUI application (not console).

For example, you can convert to the WinForms application.

Open project file and add <UseWindowsForms>true</UseWindowsForms>:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
  </PropertyGroup>
</Project>

Then:

using System;
using System.Windows.Forms;

namespace ConsoleApp
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            if (DialogResult.OK == dialog.ShowDialog())
            {
                string path = dialog.FileName;
            }
            Console.WriteLine("Hello World!");
        }
    }
}

Upvotes: 5

Michael
Michael

Reputation: 1276

If you really want to open a dialog in a console application (and command line arguments are not an option) without dependencies you can call GetOpenFileName in comdlg32.dll. pinvoke.net provides C# definitions for these methods and their parameters. Of course this is platform dependent (Windows only).

using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace DemoApp
{
    // From https://www.pinvoke.net/default.aspx/Structures/OPENFILENAME.html
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct OpenFileName
    {
        public int lStructSize;
        public IntPtr hwndOwner;
        public IntPtr hInstance;
        public string lpstrFilter;
        public string lpstrCustomFilter;
        public int nMaxCustFilter;
        public int nFilterIndex;
        public string lpstrFile;
        public int nMaxFile;
        public string lpstrFileTitle;
        public int nMaxFileTitle;
        public string lpstrInitialDir;
        public string lpstrTitle;
        public int Flags;
        public short nFileOffset;
        public short nFileExtension;
        public string lpstrDefExt;
        public IntPtr lCustData;
        public IntPtr lpfnHook;
        public string lpTemplateName;
        public IntPtr pvReserved;
        public int dwReserved;
        public int flagsEx;
    }

    public class Program
    {
        // From https://www.pinvoke.net/default.aspx/comdlg32/GetOpenFileName.html
        [DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern bool GetOpenFileName(ref OpenFileName ofn);

        private static string ShowDialog()
        {
            var ofn = new OpenFileName();
            ofn.lStructSize = Marshal.SizeOf(ofn);
            // Define Filter for your extensions (Excel, ...)
            ofn.lpstrFilter = "Excel Files (*.xlsx)\0*.xlsx\0All Files (*.*)\0*.*\0";
            ofn.lpstrFile = new string(new char[256]);
            ofn.nMaxFile = ofn.lpstrFile.Length;
            ofn.lpstrFileTitle = new string(new char[64]);
            ofn.nMaxFileTitle = ofn.lpstrFileTitle.Length;
            ofn.lpstrTitle = "Open File Dialog...";
            if (GetOpenFileName(ref ofn))
                return ofn.lpstrFile;
            return string.Empty;
        }

        public static void Main(string[] args)
        {
            var filename = ShowDialog();
            Console.WriteLine(filename);
        }
    }
}

Upvotes: 14

Related Questions