WinForms how to open file in resources folder - c#

I am new in WinForms technology. I am using .NET Framework 4.8 , Microsoft Visual Studio 2019. I put file in Resources folder.
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.

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.

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 ...
}

Related

Get the path of the file that launched my app

I'm working in my own PDF Reader using C# & Patagames/PDFium library and I am able to open files using "OpenFileDialog" and show them on the screen. However, due requirements of the boss I am not allowed to have any buttons in the screen. All we want is to click the any .PDF file (For example, in this route: C:\Users\Adaptabilidad\Desktop\Test.pdf) and launch it & show the PDF document directly, without looking for the directory of the file. I've set my ".exe" as default app, although, the PDF Reader is executed no PDF file is displayed.
I've tried Application.ExecutablePath, Application.StartUpPath after initializing the component and I'm still getting the route of my PDF reader executable (.Exe) but I need to know what the file to be open is (filepath).
How can I get the information about the .pdf file (directory can vary) that is launching my app? You can see my code below if helps.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Patagames;
using System.IO;
namespace aPDF
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "PDF Files (*.pdf)|*.pdf";
if (dialog.ShowDialog() == DialogResult.OK)
{
openfile(dialog.FileName);
}
}
public void openfile(string filepath)
{
byte[] bytes = System.IO.File.ReadAllBytes(filepath);
var stream = new MemoryStream(bytes);
Patagames.Pdf.Net.PdfDocument pdfDocument = Patagames.Pdf.Net.PdfDocument.Load(stream);
pdfViewer1.Document = pdfDocument;
}
}
}
Updates:
I've found a way. One of you guys that commented allowed me to find out how to do it.
What I used is the following sentence in my Program.cs:
public static string[] cmdLine = Environment.GetCommandLineArgs();
public static string cmd = cmdLine[1];
Then, y use "cmd" as filepath.
Why? Environment.GetCommandLineArgs(); returns 2 values, the .exe you're executing (your program) & as second value the file that you've used in order to launch that .exe.
That's it. Thank you for your answers.

C# Extract the most recent zipped file only

Finally got my code working fine, but I need to extract the most recent zipped file within the directory.
Really not sure how to go about this, can someone please point me in the correct direction, was thinking of using modified date and time, please see my code below...
using System;
using System.IO;
using System.IO.Compression;
namespace unZipMe
{
class Program
{
static void Main(string[] args)
{
DirectoryInfo file = new DirectoryInfo(#"c:\Temp\ZipSampleExtract");
if(file.Exists)
{
file.Delete(true);
}
string myDir = (#"c:\Temp\ZipSampleExtract");
bool exists = System.IO.Directory.Exists(myDir);
if (!exists)
{
System.IO.Directory.CreateDirectory(myDir);
}
//provide the folder to be zipped
//string folderToZip = #"c:\Temp\ZipSample";
//provide the path and name for the zip file to create
string zipFile = #"c:\Temp\ZipSampleOutput\MyZippedDocuments.zip";
//call the ZipFile.CreateFromDirectory() method
//ZipFile.CreateFromDirectory(folderToZip, zipFile, CompressionLevel.Optimal, false);
//specif the directory to which to extract the zip file
string extractFolder = #"c:\Temp\ZipSampleExtract\";
//call the ZipFile.ExtractToDirectory() method
ZipFile.ExtractToDirectory(zipFile, extractFolder);
}
}
}

Copy files from listbox to another directory

I'm fairly new to C# and what I'm trying to do is
Search for a file
List all matching files into a listbox
Copy the whole folder where the file is located to another place
I found bits and pieces on the web that I'm using. Right now it's only the btn_search_Click part that is working.
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_search_Click(object sender, EventArgs e)
{
try
{
listBox1.Items.Clear();
//Directory to search in
DirectoryInfo Di = new DirectoryInfo(#"D:\xxxx\Versionen");
FileInfo[] nPfad = Di.GetFiles(textBox1.Text, SearchOption.AllDirectories);
Int32 nLengePfad = nPfad.GetLength(0);
listBox1.Items.AddRange(nPfad);
}
catch (Exception)
{
MessageBox.Show("File not found");
}
}
private void btn_save_Click(object sender, EventArgs e)
{
{
string sourceFile = #"D:\Users\Public\public\test.txt";
string destinationFile = #"D:\Users\Public\private\test.txt";
// To move a file or folder to a new location:
System.IO.File.Move(sourceFile, destinationFile);
// To move an entire directory. To programmatically modify or combine
// path strings, use the System.IO.Path class.
System.IO.Directory.Move(#"C:\Users\Public\public\test\", #"C:\Users\Public\private");
}
}
}
}
My question now is, what would the code look like, if I want to select a file from the listbox and copy NOT the file but the folder it's located in to another place. I already have set a btn_save and a basic code to move files, but I need someone to show me a way to copy any selected file from the listbox or rather copy the folder of the selected file.
I'm fairly new to C# and am open for new approaches. If I'm completely wrong with the code, scratch it, show me a correct or easier way to achieve the same
You can move directly the directory with Directory.Move.
Using the FileInfo.DirectoryName you can get the Directory path from the FileInfo[] SelectedItems.
var itemsToMove = myListBox.SelectedItems.Cast<FileInfo>();
var directoriesTheyAreIn = itemsToMove.Select(x => x.DirectoryName);
var cleanDirectoriesList = directoriesTheyAreIn.Distinct();
//As many file can be in the same Dir we only need to move the dire once to move those file.
But what if Dir contains both selected and unselected files? Here I will move them all.
foreach (var path in cleanDirectoriesList)
{
// here you have to craft your destination directory
string destinationDirectory = "";
Directory.Move(path, destinationDirectory);
}
From your question it's unclear what part of the old path should be keep in the new path. but if it's based on your "D:\xxxx\Versionen" string you can simply replace this part with the new root path "NewRoot\foo\bar":
string destinationDirectory = path.Replace(#"D:\xxxx\Versionen", #"G:\FooBAR\NEWPATH\");
If you need to move only the selected file you can blindly call Directory.CreateDirectory before copying each file, as it won't throw error if the directory already exist. Grouping on directory to avoid useless instruction could have been possible but I feel like it won't be that easy to modify. Here the code will simply be: create the directory then move the file.
foreach (var item in itemsToMove) {
string destinationDirectory = #"BasedPath\" + " Craft it ";
Directory.CreateDirectory(destinationDirectory);
File.Move(item.FullName, destinationDirectory + item.Name);
}
Store the list of files into a List<FileInfo> and iterate through with foreach. This worked for me:
string destination = #"C:\Some\Destination\";
string actualFile = string.Empty;
foreach (var file in fileList)
{
actualFile = file.FullName;
File.Copy(actualFile, destination + Path.GetFileName(actualFile));
}

C# Move Files From A Folder To Another (How to code: if doesn't exist do nothing)

Beginner: Here is my code:
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
public void MoveFiles(string sourcePath, string destinationPath)
{
string[] files = Directory.GetFiles(sourcePath);
Parallel.ForEach(files, file =>
{
if ("HOW TO CODE: If the sourceFiles exist in destFolder")
{
File.Move(file, Path.Combine(destinationPath, Path.GetFileName(file)));
}
});
}
I get an error if the source files exist in destination folder. How can I correct that and is there a better way to do that?
File has the static methods Delete and Exists you can use for that very case
if(File.Exists(file))
{
if(File.Exists(destinationFile))
{
File.Delete(destinationFile);
}
File.Move(file, destinationFile);
}
I've used destinationFile to avoid redundancy.

FileSystemWatcher behaving inconsistently

I've set all the FSW properties in the designer (EnableRaisingEvents = true, filter = *.tif, IncludeSubdirectories = true, path = bla\bla\bla).
The application runs on a Windows Server 2008 R2 Standard machine and watches a local folder for created files. Instead of "C:\" i use the computers network name "GRAHAM".
The problem is that the FSW doesn't always fire when files are created/moved to the watched directory. It seems that sometimes it does, but most times it doesn't.
When debugging and watching that folder from my machine there is also some strange behaviour. If i remotely control the server machine and move files to the watched folder nothing happens. But if I move files into the watched folder from shared network folders the FSW fires, every time.
This makes it really hard for me to find the error/bug. Anyone got any ideas?
This is literally all of the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Ekonomikompetens_unikt_namn
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
StringBuilder log = new StringBuilder();
try
{
log.Append("--------------------").AppendLine().Append(DateTime.Now).AppendLine().Append("--------------------").AppendLine();
FileInfo file = new FileInfo(e.FullPath);
while (IsFileLocked(file))
{
System.Threading.Thread.Sleep(300);
}
string oFile = e.FullPath;
string nFile = oFile.Insert(oFile.Length - 4, "_" + DateTime.Now.ToString().Replace(" ", "").Replace("-", "").Replace(":", "")).Replace("\\XML Konvertering", "").Replace(#"\\GRAHAM\AnyDoc Invoices", #"\\FAKTURASERVER\AnyDoc");
if (!Directory.Exists(nFile.Substring(0, nFile.LastIndexOf('\\'))))
{
Directory.CreateDirectory(nFile.Substring(0, nFile.LastIndexOf('\\')));
File.Move(oFile, nFile);
Directory.Delete(oFile.Substring(0, oFile.LastIndexOf('\\')));
}
else
{
File.Move(oFile, nFile);
}
log.Append("* Moved and stamped file: ").AppendLine().Append(oFile).Append(" to ").Append(nFile).AppendLine().Append("--------------------").AppendLine();
}
catch (Exception x)
{
log.AppendLine().Append("*** ERROR *** ").Append(x).AppendLine().AppendLine();
}
finally
{
TextWriter tw = new StreamWriter(#"C:\tidslog\log.txt", true, Encoding.Default);
//TextWriter tw = new StreamWriter(#"C:\PROJEKT\tidsstämplarn\log.txt", true, Encoding.Default);
tw.Write(log);
tw.Dispose();
}
}
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
}
}
Note: The try-catch-finally is probably not really well made, but I'm new to coding and not really sure how to "catch" stuff, the logger has never logged an error though. Since the FSW never fires there isn't a chance for an error to occur. I'm guessing.
Subscribe to the Error event and check the error if any
In case there are large number of file being created or changed,do this
1> Increase InternalBufferSize.
Doc say this:
Increasing the size of the buffer can prevent missing file system
change events. However, increasing buffer size is expensive, because
it comes from non-paged memory that cannot be swapped out to disk, so
keep the buffer as small as possible. To avoid a buffer overflow, use
the NotifyFilter and IncludeSubdirectories properties to filter out
unwanted change notifications.
2> Also you are doing a lot of things in fileSystemWatcher1_Created which can cause the buffer to overflow causing it to miss some events...Use ThreadPool instead.

Categories

Resources