Reputation: 101
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
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
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
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