0

I am new in WinForms technology. I am using .NET Framework 4.8 , Microsoft Visual Studio 2019. I put file in Resources folder.

enter image description here enter image description here

I tried something like this

using DevExpress.XtraBars;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace accwf
{
    public partial class NhapSoDu : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        public NhapSoDu()
        {
            InitializeComponent();
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            Console.WriteLine(System.AppDomain.CurrentDomain.BaseDirectory);
            Process.Start(".../B01-DN_01_Summary.xlsx");
        }
    }
}

please guide me finish it.

Vy Do
  • 46,709
  • 59
  • 215
  • 313
  • What are the properties of those files in the project? Are you embedding them as resources, are you copying them? – Flydog57 Aug 11 '21 at 14:10
  • I copy it to project. If this way was not good practices, please guide me best practice. – Vy Do Aug 11 '21 at 14:11
  • 1
    Please forgive my ignorance, however, it would appear more sensible to embed the file PATHS into the app resources as opposed to the actual “xlsx” file itself. It just seems odd to do this since the embedded file will NEVER change without recompiling the code. If the data IS static and never changes, then I would think that it may be better to store the data into something with less overhead. Just a thought. – JohnG Aug 11 '21 at 14:17
  • My question had to do with the file properties. If you right-click the file in the _Solution Explorer_ and choose _Properties_, you'll see a property window. Under _Advanced_, there are two useful properties: **Build Action** and **Copy to Output**. If you want to embed the file into the output application as a resource, you make Build Action be _Embedded Resource_ (and the copy property to _Do Not Copy_). If you want the file to be copied to the output folder (or some sub-folder), choose Build Action as _Content_ and the copy option being one of the two copy options – Flydog57 Aug 11 '21 at 16:54

2 Answers2

2

I do this in one of my applications to open a XLSX file that is an embedded resource in my application

private void buttonOpenTemplate_Click(object sender, EventArgs e)
{
    byte[] templateFile = Properties.Resources._01__So_du_tai_khoan; // This is your Excel document in the application Resources
    string tempPath = $"{Path.GetTempFileName()}.xlsx";
    using (MemoryStream ms = new MemoryStream(templateFile))
    {
        using(FileStream fs = new FileStream(tempPath, FileMode.OpenOrCreate))
        {
            ms.WriteTo(fs);
            fs.Close();
        }
        ms.Close();
    }
    Process.Start(tempPath);
}

This requires a reference to System.IO for access to the MemoryStream and FileStream classes.

Vy Do
  • 46,709
  • 59
  • 215
  • 313
LordPupazz
  • 619
  • 3
  • 15
0

You are currently only outputting the base directory. Along with that, you're only looking for files within that base directory. Execution happens from the base directory, so your program is looking for ..\Path\to\exe\B01-DN_01_Summary.xlsx when it should be looking for ..\Path\to\exe\Resources\FilesHere\ImportExcel\B01-DN_01_Summary.xlsx

To note: embedding resources files into your application is not recommend. It's preferable to instead store their locations and allow the application to traverse your directories to find the specified file locations.

Here's an adapted version you can try:

You will need to make sure that the Copy to Output Directory property for you desire file is set to "Copy Always" or "Copy if Newer". This will ensure the directory path is created in your output directory.

namespace accwf
{
    public partial class NhapSoDu : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        public NhapSoDu()
        {
            InitializeComponent();
        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            string resourcePath = System.IO.File.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Resources\\FilesHere\\ImportExcel\\B01-DN_01_Summary.xlsx")
            
            if (File.Exists(resourcePath))
            {
                MessageBox.Show("Exists");
            }
            else 
            {
                MessageBox.Show("Doesn't Exist");
            }
            
            Process.Start(resourcePath);
        }
    }
}

This is an example of how I get PDF file documentation for a help menu I have:

public void MyMethod()
        {
            // helpMenuPath is a global var set to something like: Area/MyApp/Resources/
            string filePath = helpMenuPath;
            string[] fileNames = new string[0]; // Initialize the variable with length of 0. Directory.GetFiles() will allow for this length to be overwritten 

            // Try/Catch in case bad dir
            try
            {
                fileNames = Directory.GetFiles(filePath);
            }
            catch (IOException ioe)
            {
                // error catch for if bad dir
                MessageBox.Show($"Error in getting files: {ioe.Message}");
            }

            // Do something with files ...
        }
Jaskier
  • 1,075
  • 1
  • 10
  • 33
  • First code snippet causes error https://user-images.githubusercontent.com/1328316/129044934-1dc1baa7-1bc8-468f-b114-d7a81b4b5684.png . Second snippets, I use WinForms, not ASP.NET Core. – Vy Do Aug 11 '21 at 14:13
  • @DoNhuVy , Please see the updated answer. The second snippet is meant to be used as a reference of just another way to go about getting the files. You'd ignore the `ViewData[]` calls, set the return type to `void` and remove the `return View();` – Jaskier Aug 11 '21 at 14:28
  • Because I look it likes in ASP.NET Core. Has `IActionResult` in WinForms? – Vy Do Aug 11 '21 at 14:30
  • The second snippet *is* in ASP.NET Core- however I provided it as an example. I've modified the second snippet to be more "`WinForms` friendly" – Jaskier Aug 11 '21 at 14:34