Link to home
Start Free TrialLog in
Avatar of zachvaldez
zachvaldezFlag for United States of America

asked on

Moving files not pdf to another folder

I have 150 files with .pdf and .txt and ,png file extension in a folder.
I would like to move all non-pdf files to another folder.
Avatar of zephyr_hex (Megan)
zephyr_hex (Megan)
Flag of United States of America image

Get the list of files in the directory using Directory.GetFiles.

string[] dirs = Directory.GetFiles(targetDirectory);

Open in new window


Then, iterate over the dirs array and do a check to see if it's a pdf.  Use Path.GetExtension
Then use File.Move to move the files that are not pdfs.

foreach(var path in dirs)
{
    if(Path.GetExtension(path) != ".pdf")
    {
          File.Move(path, newDestinationPath);
     }
}

Open in new window

Avatar of Fernando Soto
Hi zachvaldez

The following code snippet should do what you need.
string sourceDir = @"C:\Working Directory";
string destDir = @"C:\Working Directory\tests\";

foreach (var file in Directory.GetFiles(sourceDir).Where(ext => Path.GetExtension(ext).ToLowerInvariant() != ".pdf"))
{
    string filename = Path.GetFileName(file);
    File.Move(file, destDir + filename);
}

Open in new window

Avatar of zachvaldez

ASKER

I'm planning to use include this in a batch file as an exe. Will it be a console app?
In my option yes, because you can execute it without the needed of a user clicking on a button or whatever. You can pass in as parameter any info needed to run the application.
The path may too long to write in the argument field. How can I modify this so I can just pass the folder names for source and destination. Probably a function or subroutine?
Will the source and destination directory always be the same?
no
The paths are too long. So maybe passing a folder name is better
To best describe it.
The Source paths are same but different folder names
The destination paths are same but different folder names
Well then it will be unavoidable for user input. In that case you can open a FolderBrowserDialog box to select the source and destination folders from the Console application. The Console app code snippet below will show you how it can be done. First you will need to add a reference to the System.Windows.Forms.dll as well as a using statement as shown below. You will also need to add a [STAThread()] attribute also shown below.
using System.Windows.Forms;

namespace ConsoleApp1
{
    class Program
    {
        static string sourceDir = "";
        static string destinationDir = "";

        [STAThread()]
        static void Main(string[] args)
        {
            FolderBrowserDialog source = new FolderBrowserDialog();
            source.Description = "Select Source Directory";
            if (source.ShowDialog() == DialogResult.OK)
            {
                sourceDir = source.SelectedPath;
            }

            FolderBrowserDialog dest = new FolderBrowserDialog();
            dest.Description = "Select Destination Directory";
            if (dest.ShowDialog() == DialogResult.OK)
            {
                destinationDir = dest.SelectedPath + @"\";
            }

        }
    }
}

Open in new window

So, build the path using a folder name as a parameter.
var newDestinationPath = string.Format("C:\\MyReallyLongPath\\{0}\\{1}", FolderParameter,Path.GetFileName(path));
File.Move(path, newDestinationPath);

Open in new window

Ideally, I prefer to pass the folder name after the exe
ThisMovefile.exe "sourcefolder","destinationfolder" eg," invoicefoldersource "to "invoicefolderstore"

I would call this in the task scheduler calling those 2 as parameters.
Hi zachvaldez;

The only way that would be possible is if the source and destination path where constant to that point which you already stated that it was not. The system would have to search all path on the drive and then at best return a collection of path that would match because the same directory name can appear in multiple path on a drive. So in short  that can not be done the way you want it to.
You can pass your parameters to a function however you want.  You'll then need to use the parameters to build the source and destination paths so you can use File.Move(), which is defined as

public static void Move(
	string sourceFileName,
	string destFileName
)

Open in new window

https://msdn.microsoft.com/en-us/library/system.io.file.move(v=vs.110).aspx

NOTE:  sourceFileName and destFileName are full paths, including the file name.
@zephyr_hex, this is what he does not want to do, "sourceFileName and destFileName are full paths".
Thanks. Just to clarify if I understood the process  and that what I have in mind would not work.
What are fixed paths are
source: "\\rst-fs01\sourcefolder\filefolder\...  + variable foldernamesource\
destination:"\\rst-fs01\destinationfolder\filefolder\.. + variable foldernamedest\

so what I need to pass in the exe are the foldernamesource and foldernamedest
move.exe "foldernamesource", "foldernamedest"

This will be in a task scheduler.
If the following will be true for each time you execute the executable
source: "\\rst-fs01\sourcefolder\filefolder\
destination:"\\rst-fs01\destinationfolder\filefolder\

Open in new window

then that will work because the path to the folder will be hard coded. I would define the two path in the Batch file and concatenate the path and the parameter sent in and pass that to the exe program.
I'm not getting anything and nowhere. Here's my code. Feel free to correct it.
 private void Form1_Load(object sender, EventArgs e)
        {
            string strsource = "", dest = "";

            PDFTransfer(strsource, dest);

            Close();
        }

  public void PDFTransfer( string strfolderSource, string strfolderdestination )
        {
           
            DateTime dt = DateTime.Today;
            string nameDate = dt.ToString("MMddyyyy");
            
            string strDestFolder = "\\\\rst-fs01\\History\\" + strfolderdestination + nameDate + "\\";
            if (!Directory.Exists(strDestFolder))
            {

                Directory.CreateDirectory(strDestFolder);
            }
            string strSourceFilePath = "\\\\rst-fs01\\Split_docs\\" + strfolderSource + "\\";


            foreach (var file in Directory.GetFiles(strSourceFilePath).Where(ext => Path.GetExtension(ext).ToLowerInvariant() != ".pdf"))
            {
                string filename = Path.GetFileName(file);
                File.Move(file, strDestFolder + filename);
            }

        }

Open in new window

My exe name  is PDFMove.exe
I'm using this PDFMove.exe "SourceFolder","DestinationFolder"
It creates a folder 10182017 which is the namedate variable but the files weren't move.
Is it because I'm passing and empty string when I initialize on strsource and dest variables.

What do I need to change or add?
How should I pass those 2 as arguments?
ASKER CERTIFIED SOLUTION
Avatar of Fernando Soto
Fernando Soto
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
where is parameter[0] or arg[0]
This has the value of parameter 0
Environment.GetCommandLineArgs()[1];

Open in new window

And this to parameter 1
Environment.GetCommandLineArgs()[2];

Open in new window

By the way
Environment.GetCommandLineArgs()[0];

Open in new window

Is the name of the program that started this instance of the application.
What a relief! I know there is power in command lines and it can be mixed with a lot of applications!
A follow up question,
In the Start Options, Command line arguments, is there a way I could leave that blank so I can use the exe with several files.
But I observe that if I do that the task scheduler fails. How about putting in code behind the arguments?
The Start Options, Command line arguments in the IDE are just there for debugging as a way to supply parameters. When you run the application's exe you need to pass in the two parameters something like this.

myapp.exe param1 param2
so can I leave it blank?I don't want to create 4 exes to accommodate  for each pair of folders - source, destination
Yes you can leave it blank but if you run the project from within the Microsoft Visual Studio IDE it will fail because the parameters will be missing.
...But with a Build exe without it or( blank command arguments)would be just fine leaving it blank..
I am not following so lets try it this way. The following code re-posted from previous post is what controls what the application does with any parameters passed into the application.
private void Form1_Load(object sender, EventArgs e)
{
    // Check to make sure the right number of parameters if not exit
    if(Environment.GetCommandLineArgs().Length != 3)
    {
        MessageBox.Show("Error : One or more parameters are missing", "Error, Missing Parameters");
        Application.Exit();
        return;
    }

    // Get the parameters from the command line. Note parameter 1 is source and two is dest.
    string strsource = Environment.GetCommandLineArgs()[1];
    string dest = Environment.GetCommandLineArgs()[2];

    PDFTransfer(strsource, dest);

    Close();
}

Open in new window

The above code test to see the number of items held in the array Environment.GetCommandLineArgs(). As shown above if it does not contain 3 elements the program will be terminated otherwise it will continue. You can change that code to accomplish what you need. For example accept 0, 1, or 2 parameters but you need to identify which case the application was started in and handle that in code
Thanks for your help Fernando.
I tried to change .move to .copy here...
foreach (var file in Directory.GetFiles(sourceDir).Where(ext => Path.GetExtension(ext).ToLowerInvariant() == ".pdf"))
{
    string filename = Path.GetFileName(file);
    File.Move(file, destDir + filename);

Open in new window

}
I get error: "The target file is directory not a file.."

I have a folder in the target where I'd like to paste all the copied files from the source.
Make sure that destDir + filename make a valid path and that \ is not missing between destDir and filename.