I am developing an application and I need to read the EXIF details of JPG file.
I am able to do so with an OpenFileDialog button but, I want it to be so that a user can open a JPG file with my application (right click>Open with) and I could get the path of the JPG file in string.
I just want to know how to get the path of the file on which the user right clicked ad selected open with "My Application"
You need to register your application for the JPG file extension in the Registry as described here: https://msdn.microsoft.com/en-us/library/windows/desktop/cc144175(v=vs.85).aspx
If you know how to get the EXIF data already and just want users to be able to right-click a JPG file > Open with > Select your application and then get the filename they're trying to open, you can do this:
private void testButton_Click(object sender, EventArgs e)
{
string[] cmdLineArgs = Environment.GetCommandLineArgs();
string jpgFilenameToOpen = "None";
if (cmdLineArgs.Length > 1)
{
jpgFilenameToOpen = cmdLineArgs[1];
}
YourGetEXIFDetailsMethod(jpgFilenameToOpen);
}
The Environment.GetCommandLineArgs() returns an array with all command line arguments that was passed to your application on load. Normally, if they just pass a filename, it should be the 2nd item in the array.
You can also loop through the arguments if needed by doing this:
foreach (var arg in cmdLineArgs)
{
MessageBox.Show(arg.ToString());
}
Edit:
I just realized I'm not sure if you need to accept only one JPG filename at a time or if you need to accept multiple JPG files at once. If it's the latter, here's some updated code that can loop through all the command-line arguments and do something with only JPG/JPEG files:
private void Form1_Load(object sender, EventArgs e)
{
string[] cmdLineArgs = Environment.GetCommandLineArgs();
List<string> jpgFilenamesToAnalyze = new List<string>();
foreach (var arg in cmdLineArgs)
{
if (arg.Contains(".jpg") || arg.Contains(".jpeg"))
{
jpgFilenamesToAnalyze.Add(arg);
}
}
if (jpgFilenamesToAnalyze.Count > 0)
{
StringBuilder sbJPGFiles = new StringBuilder();
sbJPGFiles.AppendLine("Found " + jpgFilenamesToAnalyze.Count + " images to analyze:\n\nFiles:");
foreach (var jpgFilename in jpgFilenamesToAnalyze)
{
// YourGetEXIFDataMethod(jpgFilename)
sbJPGFiles.AppendLine(jpgFilename);
}
MessageBox.Show(sbJPGFiles.ToString());
}
else
{
MessageBox.Show("No images found to analyze");
}
}
Related
I need to convert images(like .jpg) to PDF files for an assignment for school. I have a ListBox where I put the pages of the PDF file, so the user can reorder the list and convert the files in that order.
I have the files in a temporary folder in order to get the files there to convert them to PDF.
My problem here is : how do I convert the files with the order that the user had chosen?
I already searched and I tried to do a Class with the strings ID and Name so i get the ID from the item in the ListBox and change it on a new list. And i think after, I do a foreach() loop where I get the files from the temporary folder and merge them in a new PDF file, but to do in the order I want, I think I have to compare the name of the file with the name in the list and, if it matches, convert and add it, if not, pass to the next file.
But I don't know how to do it.
Can please someone help me getting this right?
Thanks in advance!
I'm sending my code to:
//the open files button
private void proc2_Click(object sender, EventArgs e)
{
OpenFileDialog dialogo = new OpenFileDialog();
dialogo.Title = "Search files";
dialogo.InitialDirectory = #"E:\";
dialogo.Filter = "Images (.bmp,.jpg,.png,.tiff,.tif) |*.bmp;*.jpg;*.png;*tiff;*tif|All of the files (*.*)|*.*";
DialogResult resposta = dialogo.ShowDialog();
if (resposta == DialogResult.OK)
{
string caminhoCompleto = dialogo.FileName;
caminho2 = dialogo.SafeFileName;
caminhotb2.Text = caminhoCompleto;
string fish = "";
string path = #"C:\temporario";
if(Directory.Exists(path))
{
fish=Path.Combine(path, caminho2);
}
else
{
Directory.CreateDirectory(path);
fish = Path.Combine(path, caminho2);
}
File.Create(fish);
listaimg.Items.Add(caminho2);
}
}
public string[] GetFilesImg4() //jpg files
{
if (!Directory.Exists(#"C:\temporario"))
{
Directory.CreateDirectory(#"C:\temporario");
}
DirectoryInfo dirInfo = new DirectoryInfo(#"C:\temporario");
FileInfo[] fileInfos4 = dirInfo.GetFiles("*.jpg");
foreach (FileInfo info in fileInfos4)
{
if (info.Name.IndexOf("protected") == -1)
list4.Add(info.FullName);
}
return (string[])list4.ToArray(typeof(string));
}
If both actions happen in the same process, you can just store the list of file names in memory (and you already do add them to listaimg):
public string[] GetFilesImg4() //jpg files
{
string tempPath = #"C:\temporario";
if (!Directory.Exists(tempPath))
{
foreach (string filename in listimga.Items)
{
if (!filename.Contains("protected"))
list4.Add(Path.Combine(tempPath, filename);
}
}
return (string[])list4.ToArray(typeof(string));
}
if these are different processes then you can just dump content of your listimga at some point and then read it from the same file. In the example below I store it to file named "order.txt" in the same directory, but logic may be more complicated, such as merging several files with a timestamp and such.
// somewhere in after selecting all files
File.WriteAllLines(#"c:\temporario\order.txt", listimga.Items.Select(t=>t.ToString()));
public string[] GetFilesImg4() //jpg files
{
string tempPath = #"C:\temporario";
if (!Directory.Exists(tempPath))
{
var orderedFilenames = File.ReadAllLines(Path.Combine(tempPath, "order.txt")); // list of files loaded in order
foreach (string filename in orderedFilenames)
{
if (!filename.Contains("protected"))
list4.Add(Path.Combine(tempPath, filename);
}
}
return (string[])list4.ToArray(typeof(string));
}
it's also a good idea to examine available method on a class, such as in this case string.IndexOf(s) == -1 is equivalent to !string.Contains(s) and the latter is much more readable at least for an English speaking person.
I also noticed that your users have to select documents one by one, but FileOpen dialogs allow to select multiple files at a time, and I believe it preserves the order of selection as well.
If order of selection is important and file open dialogs don't preserve order or users find it hard to follow you can still use multiple file selection open dialog and then allow to reorder your listimga list box to get the order right.
I'm trying to load a picture into a pictureBox from a string array of pictures I created using Directory.GetFiles(). I believe I am not setting properly setting the picFile correctly.
I've than created a pictureBox_Click event to load subsequent pictures but have not written that event handler
string fileEntries = "";
private void showButton_Click(object sender, EventArgs e)
{
// First I want the user to be able to browse to and select a
// folder that the user wants to view pictures in
string folderPath = "";
FolderBrowserDialog folderBrowserDialog1 = new FolderBrowserDialog();
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
folderPath = folderBrowserDialog1.SelectedPath;
}
// Now I want to read all of the files of a given type into a
// array that from the path provided above
ProcessDirectory(folderPath);
// after getting the list of path//filenames I want to load the first image here
string picFile = fileEntries;
pictureBox1.Load(picFile);
}
public static void ProcessDirectory(string targetDirectoy)
{
// Process the list of files found in the directory.
string[] fileEntries = Directory.GetFiles(targetDirectoy);
}
// event handler here that advances to the next picture in the list
// upon clicking
}
If I redirect the string array to the Console I see the list of files in that directory but it also has the full path as part of the string - not sure if that is the issue.
string[] fileEntries = ProcessDirectory(folderPath);
if (fileEntries.Length > 0) {
string picFile = fileEntries[0];
pictureBox1.Load(picFile);
}
You have fileEntries declared twice.
public static string[] ProcessDirectory(string targetDirectoy) {
return Directory.GetFiles(targetDirectoy);
}
Now I want to read all of the files of a given type into a
array that from the path provided above
So you have to change the signature of the method ProcessDirectory to return a string affy that includes all the picture files, you can use the search pattern to get files with specific extension as well. You can use the following signature:
public static string[] ProcessDirectory(string targetDirectoy)
{
return Directory.GetFiles(targetDirectoy,"*.png");
}
after getting the list of path//filenames I want to load the first image here
So you can call the method to get all files in that specific directory with specific extensions. And then load the first file to the picturebox if the array having any files, you can use the following code for this:
var pictureFiles = ProcessDirectory(folderPath);
if (pictureFiles.Length > 0)
{
// process your operations here
pictureBox1.Load(pictureFiles[0]);
}
I'm trying to upload multiple files and just get the filename of them.
When I'm trying to do that it just uploads one file.
So it uploads the files with the full path(And it works).
private void bChooseFolder_Click(object sender, EventArgs e)
{
CoreClass.OPENDIALOG.Multiselect = true;
string oldFilter = CoreClass.OPENDIALOG.Filter;
CoreClass.OPENDIALOG.Filter = "(*.csv) | *.csv";
if (CoreClass.OPENDIALOG.ShowDialog() == DialogResult.OK)
tbFolderPath.Text = string.Join(FileSeperator, CoreClass.OPENDIALOG.FileNames);// <-- this works, but here I get the full path
CoreClass.OPENDIALOG.Filter = oldFilter;
CoreClass.OPENDIALOG.Multiselect = false;
}
And so I get just the Filename but it uploads just one File:
private void bChooseFolder_Click(object sender, EventArgs e)
{
CoreClass.OPENDIALOG.Multiselect = true;
string oldFilter = CoreClass.OPENDIALOG.Filter;
CoreClass.OPENDIALOG.Filter = "(*.csv) | *.csv";
if (CoreClass.OPENDIALOG.ShowDialog() == DialogResult.OK)
tbFolderPath.Text = string.Join(FileSeperator, System.IO.Path.GetFileNameWithoutExtension(CoreClass.OPENDIALOG.FileName)); // <-- Doesn't work. Just one File.
CoreClass.OPENDIALOG.Filter = oldFilter;
CoreClass.OPENDIALOG.Multiselect = false;
}
OK, If you are developing WinForms app then you are using OpenFileDialog which contains 2 properties:
FileName gets or sets a string containing the file name selected in the file dialog box.
FileNames gets the file names of all selected files in the dialog box.
Then first one will never contains few files and you should use it only in Multiselect = false; mode.
If you need to show all file names in one textbox then you can use String.Join method and LINQ to enumerate collection and get file name without extension for each element:
if (CoreClass.OPENDIALOG.ShowDialog() == DialogResult.OK)
tbFolderPath.Text = string.Join(FileSeperator, CoreClass.OPENDIALOG.FileNames.Select(x => System.IO.Path.GetFileNameWithoutExtension(x)).ToArray()); // <-- Doesn't work. Just one File.
I have several issues within a windows forms application. So far, I have managed to loop though a folder and display the reuslts in a text box. Once these have returned, the user can check the results and the error files can be removed using the following;
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
File.Delete(file);
}
}
What I want to do now, after the error files have been removed, is copy the same files from a backup folder (the only difference in the filenames is the file extention) I am using a seperate button for this action. Any help on this final step would be greatly appreciated.
Use Path class to get File names without extensions, combine paths and more, as an example:
StringCollection filesToBeReplaced = new StringCollection();
private void button2_Click(object sender, EventArgs e)
{
foreach (string file in Directory.GetFiles(#"\\" + textBox1.Text + #"\\d$\\NSB\\Coalition\\EDU", "*.err").Where(item => item.EndsWith(".err")))
{
//Now you have file names without extension
filesToBeReplaced.Add(Path.GetFileNameWithoutExtension (file));
File.Delete(file);
}
}
private void CopyGoodFilesFromSource()
{
foreach(string fileName in filesToBeReplaced)
{
string sourceFilePath = Path.Combine("YOUR FOLDER FOR GOOD FILES",
Path.ChangeExtension(fileName,"Your Extension")) ;
string destinationPath = Path.Combine("Destination Folder",
Path.ChangeExtension(fileName, "Your Extension in destination folder");
File.Copy(sourceFilePath , destinationPath, true);
}
}
so basically i have a data grid view that goes into a file and loads all of the .txt file names into a data grid view. What i need to do is when i click on a certain file in data grid view, it will open up the contents of that file into a list view.
Can anyone help as i am stuck?
I am guessing its something like:
if data grid view value = .txt file in the folder then load contents into listview.
sounds easy enough just unsure how to code this.
Thank you
I have this so far but still does not work:
private void gridProfiles_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (gridProfiles.Rows[e.RowIndex].Cells[0].Value != null)
{
var path = gridProfiles.Rows[e.RowIndex].Cells[0].Value.ToString();
path = Path.Combine(rootDirectory + "\\Profiles\\", path);
if (File.Exists(path))
{
String[] lines = File.ReadAllLines(path);
foreach (var line in lines)
{
lstProcesses.Items.Add(path);
}
}
}
}
When i run this it gets ti if(file.exists(path) and then skips over it
route directory:
private static string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\My File";
static void CreateDirectory()
{
string rootDirectory = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\My File";
if (!Directory.Exists(rootDirectory)) { Directory.CreateDirectory(rootDirectory); }
if (!Directory.Exists(rootDirectory + "\\Profiles")) { Directory.CreateDirectory(rootDirectory + "\\Profiles"); }
Looks like you create incorrect path, or you are reading incorrect cell value. Use overloaded Path.Combine which accept list of path parts. Also instead of adding path to list you should add line.
Following code will show you error message if file not exist with path where it tries to look for file. Also it will show error message if there is no file name in grid cell.
private void gridProfiles_CellClick(object sender, DataGridViewCellEventArgs e)
{
object value = gridProfiles.Rows[e.RowIndex].Cells[0].Value;
if (value == null)
{
MessageBox.Show("Cannot get file name from grid");
return;
}
var file = value.ToString();
var path = Path.Combine(rootDirectory, "Profiles", file); // create path
if (!File.Exists(path))
{
MessageBox.Show(path + " not found");
return;
}
foreach(string line in File.ReadLines(path))
lstProcesses.Items.Add(line); // add line instead of path
}