I have an C# application to load some files into my database, but when I try to load the file the application only load from one location (C:), but I need to be able to load the files from any location.
I use this function to load the files
private void cmdArchivoTotal_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dialogoArchivo = new OpenFileDialog();
dialogoArchivo.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
dialogoArchivo.Filter = "CSV Files (*.csv)|*.csv";
if (dialogoArchivo.ShowDialog().Value)
txtArchivoTotal.Text =
System.IO.Path.GetFullPath("\\"+dialogoArchivo.SafeFileName);
}
At first I was thinking this was for run the application in debug mode, but even deployed the application only load the files from "C:\".
How can I load files from any disk and directory?
You're using OpenFileDialog.SafeFileName, which only returns the filename, not the path. By prepending \, you're constricted to reading files from the current disk's root.
Just use the FileName property, which contains the full path:
txtArchivoTotal.Text = dialogoArchivo.FileName
Related
I have a PDF file that I would like to load with a button click. I can reference the file in debug mode, but when I publish the project, the pdf doesn't migrate over or 'install' with the project.
The file is located in Resources/file.pdf
In the WPF form, I call the "OpenFile_Click" function on click.
Here is my function:
private void OpenFile_Click(object sender, RoutedEventArgs e)
{
string appPath = AppDomain.CurrentDomain.BaseDirectory;
Process.Start(appPath + "Resources/file.pdf");
}
This clearly doesn't work to open that file. I can add ../../ in front of the Resources folder and it will open in debug, but that isn't very helpful.
So, what is the best option for opening an external file like a PDF?
After setting Properties\Copy to Output Directory = Copy if Newer as suggested by Clemens, I would also recommend the use of System.IO.Path.Combine to ensure the correct path delimiter for the platform.
If there is still an error when invoking the Process.Start then try starting "explorer.exe" with the combined file name. I successfully tested the following, see if you can repro.
private void OpenFile_Click(object sender, RoutedEventArgs e)
{
var filePath = System.IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Resources",
"file.pdf"
);
Process.Start("explorer.exe", filePath);
}
I have an application which currently provides the user with the ability to view a PDF file inside the application by using File->Open, browsing to the location of the PDF file using a Microsoft.Win32.OpenFileDialog, and then displaying that PDF file in a System.Windows.Controls.WebBrowser in the GUI.
I am creating the OpenFileDialog and setting the file extensions it can open using:
/*Create Open File dialog */
Microsoft.Win32.OpenFileDialog OFDlg = new Microsoft.Win32.OpenFileDialog();
/*Set filter for file extension and default file extension */
OFDlg.DefaultExt = ".pdf";
OFDlg.Filter = "PDF Documents (.pdf)|*.pdf";
I now want to extend this, so that the user can open a ZIP folder containing a single PDF document, and display that PDF document in the same way that I am above.
I tried changing the filter to allow .zip files, i.e.
OFDlg.DefaultExt = ".pdf|.zip";
OFDlg.Filter = "PDF Documents (.pdf)|*.pdf|ZIP|*.zip";
but when I browse to the location of the .zip file in the OpenFileDialog, the .zip folder is not displayed there- only normal folders and PDF documents (other documents in that directory, such as .doc & .xls are not displayed in the OpenFileDialog).
My reason for wanting to be able to open the contents of a .zip file directly from the .zip, rather than navigating to that file itself, is so that I can add public/private key encryption to the .zip, so that its contents can only be read securely.
I know that there could in theory be problems if the .zip contains more than one file, but I intend to send each encrypted file in its own zip folder, so it can be assumed that any zip file that the user is trying to open contains a single .pdf, and nothing else.
So my questions are:
How can I make .zip folders visible from the OpenFileDialog?
How can I make the selection of that .zip folder automatically open and display its contents (a single PDF file) in the System.Window.Controls.WebBrowser that I am currently using to display PDFs in my GUI?
Edit 1
I tried changing my OpenFile() method to the following code:
/*Set filter for file extension and default file extension */
OFDlg.DefaultExt = ".pdf";
OFDlg.DefaultExt = ".zip";
OFDlg.Filter = "PDF Documents (.pdf)|*.pdf";
OFDlg.Filter = "ZIP Folders (.ZIP)|*.zip";
but when I now run my application, and browse to the same location, although the .zip folder is now shown in the OpenFileDialog, the .pdf files no longer are... and if I double click the .zip folder, my application breaks, and I get a runtime error on the line
PdfPanel.OpenFile(docFP);
which says:
An unhandled exception of type 'System.AccessViolationException' occurred in MoonPdfLib.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I guess that's to do with the MoonPDF library that I'm using to read the PDFs being unable to handle the .zip extension?
How would I resolve this to be able to open the PDF inside the ZIP?
Edit 2
Ok, so I've resolved the issue about only being able to see either the PDF files or the .ZIP folders (not both at the same time), by moving the functionality into two separate methods- one to display the PDF direct from the PDF's filepath, and another to display the PDF from the path of the .ZIP folder holding it.
The method for displaying the PDFs directly currently works (it is essentially the code in the first bit of code I've quoted). However the method for displaying the PDFs from the ZIP currently doesn't work...
I understand the reason for this- it's because I am passing a .zip folder to the OpenFile method... The code for this method currently looks like this:
private void openZipMenuItem_click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog OZipDlg = new Microsoft.Win32.OpenFileDialog();
OZipDlg.DefaultExt = ".zip";
OZipDlg.Filter = "ZIP Folder (.zip)|*.zip";
Nullable<bool> result = OZipDlg.ShowDialog();
if (result == true)
{
/*Open document */
string filename = OZipDlg.FileName;
//fnTextBox.Text = filename;
zipFP = OZipDlg.FileName;
/*browser.Navigate(docFP); ERF (27/05/2016 # 0935) Comment this line- I want to use PdfPanel to open docFP, not browser */
Console.WriteLine("Panel height: " + PdfPanel.ActualHeight);
PdfPanel.OpenFile(zipFP);
}
}
When I try to call this function to open a .zip, I get a runtime exception which says:
AccessViolationException was unhandled
An unhandled exception of type 'System.AccessViolationException' occurred in MoonPdfLib.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I understand that I can't display a Zip folder in the PdfPanel (which is a MoonPdfPanel that I am using from the MoonPdfLibrary), so I know that I will get an exception here.
How can I pass the contents of zipFP to the call to PdfPanel.OpenFile(), rather than passing zipFP itself to it?
Edit 3
Ok, so my code is currently extracting the PDF file successfully from the ZIP folder when I open it- I can see that it is copied to the directory I have specified. I am now trying to get the PDF to be displayed automatically in the PDF Panel on my application- I've done this by adding the following code:
try{
string extractPath = #"C:\Documents";
using(ZipArchivev zip = ZipFile.Open(zipFP, ZipArchiveMode.Read))
foreach(ZipArchiveEntry entry in zip.Entries){
try{
ZipFile.ExtractToDirectory(zipFP, extractPath);
Console.WriteLine("zipFP: " + zipFP);
}catch(System.IOException){
Console.WriteLine("File already exists...");
}
}
string ExtractedPDF = string.Concat(extractPath, zipFP);
PdfPanel.OpenFile(ExtractedPDF);
}catch(AccessViolationException ex){
Console.WriteLine("Can't display a zip in the PDF panel..." + ex.InnerException);
}
But when my code tries to execute the line PdfPanel.OpenFile(ExtracedPDF);, I get an exception that says:
FileNotFoundException was unhandled | An unhandled exception of type 'System.IO.FileNotFoundException' occurred in MoonPdfLib.dll'
I understand that this is happening because the variable I am trying to display in the PDFPanel, ExtractedPDF actually holds the path of the folder containing the PDF, and not the PDF itself- How do I give it the name of the PDF file, when I don't actually know what the PDF file will be called?
Here is something works similar to your requests, the logic behind the code is:
Only display zip and pdf files in the OpenFileDialog
If user selected a pdf file, show it in the panel
If user selected a zip file, change the directory of the OpenFileDialog to the zip file(treat it like a folder)
Example code (working code....):
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "PDF files (.pdf)|*.pdf;*.zip";
ofd.ShowDialog();
//reopen OpenFileDialog if it is zip file. this part can be improved.
if (ofd.FileName.EndsWith(".zip"))
{
ofd.InitialDirectory = ofd.FileName;
ofd.ShowDialog();
}
//if it's a PDF, note that you don't really need this check,
//as the only file can reache here will be a PDF,
//and it can be the temporary file that inside a zip.
if(ofd.FileName.EndsWith(".pdf"))
{
//show it in your PdfPanel
}
Edit, based on your new comments and added code. you need to change your code to the following as your current code is mistaken directory with the file:
try{
string extractPath = #"C:\Documents";
string ExtractedPDF ="";
using(ZipArchivev zip = ZipFile.Open(zipFP, ZipArchiveMode.Read))
foreach(ZipArchiveEntry entry in zip.Entries){
try{
ExtractedPDF= Path.Combine(extractPath, entry.FullName);
entry.ExtractToFile(ExtractedPDF,true);
}catch(System.IOException){
Console.WriteLine("error during extraction...");
}
}
if( System.IO.File.Exists(ExtractedPDF))
{
PdfPanel.OpenFile(ExtractedPDF);
}
}catch(AccessViolationException ex){
Console.WriteLine("Can't display a zip in the PDF panel..." + ex.InnerException);
}
If you want to support multiple file formats in an open file dialog, you need to add a third (or better first) option, that aggregates all supported file extensions:
OFDlg.Filter = "Supported file formats|*.pdf;*.zip|PDF Documents|*.pdf|ZIP files|*.zip";
First, regarding showing the files in the open file dialog. Your initial method for doing this was correct. Your updated code now first sets the filter to show PDFs, then replaces that filter with one that shows zip files. The standard file open dialog isn't designed to show different file types at the same time. The right way to handle that is to give the user the option for which file types they want to show.
Typically, an "All files" option is added as well (with . as the search pattern). This way if the file type the user wants to open isn't available in the list, they can see it regardless.
As for opening the PDF file that is in the zip file, you need to take are of extracting the PDF file yourself. This question has some options for how to do that.
When this method is invoked I get the following stack trace when it reaches OpenAsync():
System.Exception: Shape file not found:
C:\Users\Laura\Desktop\shapes\TOTALMAP\OH_Line_6600v_Expired.shp at
RuntimeCoreNet.Interop.HandleException(Boolean retVal) at
RuntimeCoreNet.CoreFeatureSource.FromShapefile(String filename) at
Esri.ArcGISRuntime.Data.ShapefileTable.OpenAsync(String filename)
at ShapeSQLiteGISDemo.MainPage.d__3.MoveNext()
I have a .dbf and .shx file in the same folder with the same name and I've been running Visual Studio in Administrator Mode.
private async void ImportShapes(object sender, RoutedEventArgs e)
{
try
{
//Get path from file picker
var picker = new FileOpenPicker { SuggestedStartLocation = PickerLocationId.Desktop };
picker.FileTypeFilter.Clear();
picker.FileTypeFilter.Add(".shp");
var file = await picker.PickSingleFileAsync();
//convert folder contents to a ShapefileTable
var shapefile = await ShapefileTable.OpenAsync(file.Path);
//save object to database
_DatabaseConnection.Insert(shapefile);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
//call a method that loads shapes from the database
LoadDatabaseOntoMap();
}
Any help much appreciated.
I believe the problem is that with Store and UWP apps the .shp file has to be moved to a folder in the local storage before the application can open it.
Will set as the accepted answer if this solves the problem.
EDIT: This is indeed the case, because I was choosing a single file with the the file picker I only had access to that one file. To get multiple files I used the folder picker and filtered away any files that weren't useful.
Try using an app like notepad to open the file by pasting in the path:
C:\Users\Laura\Desktop\shapes\TOTALMAP\OH_Line_6600v_Expired.shp
Does the app open the file?
Are there other examples of shape files that do open? Could this file simply be corrupted?
I have code below. It works fine. But I would like to locate the "sound.wav" file the folder of the project. I mean ı don't want to put it in "D:\audio\background\sound.wav". I put the audio file the folder of the project but I couldn't do that . What changes should I do in System.Uri(#"D:\audio\background\sound.wav"))"
Thanks.
my simple program is this. I just want to play sound.wav file from home folder.
private void button1_Click(object sender, EventArgs e)
{
var background = new System.Windows.Media.MediaPlayer();
background.Open(new System.Uri(#"D:\sound.wav"));
background.Play();
}
You can use Environment.CurrentDirectory to get current working directory of your application. Then use Path.Combine to create path to audio folder inside working directory:
var path = Path.Combine(Environment.CurrentDirectory, "audio", "sound.wav");
If you want add your audio files in the resources properties->resources->addresource,after you done that just do this:
SoundPlayer sndplayr = new SoundPlayer(YourNameSpace.Properties.Resources.TDB_Groove_04_140_BPM__RC_);
sndplayr.Play();
//TDB_Groove_04_140_BPM__RC_ was a file i have and added to my project just as example
If you prefer to place files in startup folder then:
var background = new System.Windows.Media.MediaPlayer();
background.Open(new Uri(Application.StartupPath + #"\YourWavFile.wav"));
background.Play();
Assuming you have a directory called audio in your project you could access the file with a string like this:
"..\audio\sound.wav"
Or if your application is being run in a directory further down in your project you can use "~" to access the home directory
In my silverlight application I would like to be able to select a file from an OpenFileDialog window and upload/copy it to a local folder in my Silverlight project. I am already able to setup a OpenFileDialog window and set some options to it, but unfortunately I can't find a way to create a filestream and then copy it to a local folder.
private void Change_Avatar_Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openfile = new OpenFileDialog();
openfile.Multiselect = false;
openfile.Filter = "Images files (*.bmp, *.png)|*.bmp;*.png";
if ((bool)openfile.ShowDialog())
{
}
}
I've tried looking at many tutorials on the net, but they only seem to send the file directly to the UploadFile method in silverlight what I do not want to do at the moment.
Thank you, Ephismen.
You can't just write files to local folders without prompting the user a second time (e.g. save as dialog http://www.silverlightshow.net/items/Using-the-SaveFileDialog-in-Silverlight-3.aspx)
You could write it to isolated storage instead: http://blogs.silverlight.net/blogs/msnow/archive/2009/05/21/71909.aspx.
If you want specific examples (e.g. going straight from OpenFileDialog to Isolated storage) I strongly recommend you use Google. The first match on "silverlight openfiledialog to isolated storage" is this: http://forums.silverlight.net/forums/t/201362.aspx