0

I'm trying to create a copy button for files with this specific function:

When I write in the textbox for example "KL5050" and then press the copy button, I want to copy the file KL5050 from a specific folder and paste it to another specific folder without asking or opening any dialog or window, just click, copy and paste.

It doesn't matter the file format, it could be TXT, doc, PDF, JPEG, etc., as long as it matches the text from the textbox to any existing file in the folder it will be copied to another folder.

Also, if the file doesn't exist from the copy folder, get a warning "file not found".

The code that I have so far has two textboxes, the first is called serieBox, that one only requires input data (if is empty opens a window) before proceeding to the next box, then the next box is named recetaBox, which is the one where I type the name of file and then clicking the button, the program will look for the file and copy it to the different folder. So far I don't know where to put the second box, recetaBox. Is not in the code yet.

private void cargarButton_Click(object sender, EventArgs e)
        {
            if (serieBox.Text == string.Empty)
            {
                SerieWin openForm = new SerieWin();
                openForm.ShowDialog();
            }
            else
            {
                try
                {
                    string dircopyFrom = @"C:\From\";
                    string dircopyTo = @"C:\To\";
                    string[] files = Directory.GetFiles(dircopyFrom);

                    foreach (string file1 in files)
                    {
                            string filename1 = Path.GetFileName(file1);
                            File.Copy(file1, dircopyTo + "\\", true);
                    }
                }
                catch (Exception ex)
                {
                }
Ken White
  • 123,280
  • 14
  • 225
  • 444
fjleon
  • 5
  • 2
  • What, if any, error are you getting? – Jacob Lockard Oct 24 '21 at 21:47
  • I don't get any erros, it just doesnt work so far when I click the button and I still dont know how to implement the second textbox "recetaBox" the one that tells which file to copy in the code. – fjleon Oct 24 '21 at 22:51
  • `@"C:\To\"` already has it's trailing backslash. Don't add another one when you're using it in `File.Copy(file1, dircopyTo + "\\", true);`. Just use `dircopyTo`. But that's not the problem you're having, which is totally unclear to me. We're not going to write the code for you to get the filename from the user, and when you figure that out you're going to have to use that filename to check against `file1` to see if it's at least a partial match before copying it, or better yet use it as a filter when you get the list of files. – Ken White Oct 25 '21 at 00:34
  • 2
    @Ken just wanted to point out that File.Copy doesn't accept a directory as a destination; it must nominate a file name too – Caius Jard Oct 25 '21 at 05:17
  • @CaiusJard: You apparently stopped reading before you got to *But that's not the problem you're having*. :-) – Ken White Oct 25 '21 at 05:25
  • @CaiusJard I think you are right and that's why the file won't copy. although @fjleon started it, just didn't finished it. the `"\\"` should completely replaced with `filename1` – iѕєρєня Oct 25 '21 at 05:46
  • @KenWhite Thing is, to a large extent I think that *is* (one of) the problems in the OP's code - the code would at least do something if a file name were given. I should have made it more clear in my comment that I'm sure *you're* aware copy needs a filename, it's just that (as written) it seems like you're saying the problem is the slash (implication being that a dir is acceptable).. Actually I don't think windows cares about double slashes in paths either! – Caius Jard Oct 25 '21 at 05:51
  • @fjleon Putting an empty catch block is pretty fatal; I was quite amused by "I don't get an error" - heh, yeah, we don't if we throw them away.. One tip, aside from "never put an empty catch block", if you go on the Debug menu, Windows..Exceptions and then put a tick next to CLR the debugger will stop as soon as any exception occurs whether it is handled or not. This can be really useful to debug, because you see the very first place the error occurs; in this case you'd have probably seen some argument exception relating to bad input to file copy – Caius Jard Oct 25 '21 at 05:57
  • @CaiusJard: Yes, Windows very much cares about double-slash characters in pathnames, as that would indicate that there are two folders there, not one. And all I did was point out one issue in the OP's code (and that it was NOT the major problem with their code). I can understand your criticism if I had written an answer, but all I did was leave a comment to pass along some additional information. Not sure why you're still wanting to beat this dead horse. – Ken White Oct 25 '21 at 12:53
  • *Windows very much cares about double-slash characters in pathnames* - except, it really doesn't seem to in my tests.. `Directory.CreateDirectory(@"c:\temp\\a\\\b\\\\\\\\\\\\c")` functions identically to `Directory.CreateDirectory(@"c:\temp\a\b\d")` - But it's OK, we're "all good in the hood" and the OP's sorted.. – Caius Jard Oct 25 '21 at 13:43

1 Answers1

1

The only thing you haven't been totally clear on is whether KL5050 is the start, end, whole or part of the FileName but it's easy to fix

  string[] files = Directory.GetFiles(dircopyFrom);

  foreach (string file in files)
  {
    var fn = Path.GetFileNameWithoutExtension(file);
    
    if(!fn.Contains(recetaTextBox.Text, StringComparison.OrdinalIgnoreCase))
      continue;

    fn = Path.GetFileName(file);
    File.Copy(file, Path.Combine(dircopyTo, fn), true);
  }
} catch(Exception ex){
  MessageBox.Show(ex.Message);
}

Take away points:

  • do some check like Contains, StartsWith, EndsWith etc

  • use Path.Combine to build paths; .net runs on more than just windows and different systems have different directory separator chars

  • File.Copy takes a destination path that must contain a FileName too, not just a directory. The destination file can be renamed during copy by tweaking the name

  • don't ever put an empty catch block. At the very least always do a MessageBox.Show(ex.Message); especially working with files. Having a program that does nothing when a button is clicked is very frustrating. If at least you get a "file is in use by another program" when trying to copy, then you can do something about it.. but if you swallow that exception and throw it away rather than surfacing it then you'll have a really tough time tracking down any problems

  • if you want a slight efficiency boost you can use the contents of recetaTextBox.Text to form a filter to GetFiles, e.g GetFiles(dircopyFrom, recetaTextBox.Text+"*.*") - that is conceptually equivalent to "StartsWith". You can read more about getfiles that takes a search pattern in the fine manual - pattern matching is very basic though, if you want any advanced stuff like Regex, or even just case sensitivity, you'll need to do it in your own code

  • the directory you're copying to has to exist. I didn't put anything in the code to ensure this but note that it's safe to call Directory.CreateDirectory(dirCopyTo) even if it already exists, so if there's a chance the dir won't exist, you can always call CreateDirectory before you call copy to make sure it does

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • I try the fix but Contains `if(!fn.Contains(recetaTextBox.Text, StringComparison.OrdinalIgnoreCase))` is underlined red with build error CS1501 No overload for method 'Contains' takes 2 arguments, any advice on this. – fjleon Oct 25 '21 at 06:34
  • Looks like you're using a version of .net that doesn't have a second argument that allows you to choose case insensitive so.. First off, do you want it case sensitive or not? Second, what kind of match do you want KL5050 to be? KL5050.txt? KL5050hello.txt? helloKL5050.txt? helloKL5050hello.txt? (Exact, StartsWith, endswith, contains etc) – Caius Jard Oct 25 '21 at 06:36
  • I'm using .net 3.5 since this is a basic program for a Windows XP old system, for now the match is going to be exact but I appreciate if you can post also for contains, unless the .net 3.5 doesn't support it. Also needs to be case sensitive if is possible. – fjleon Oct 25 '21 at 06:45
  • Case *sensitive* can be achieved by just deleting the `, StringComparison.OrdinalIgnoreCase` bit leaving a single argument to Contains. If you want *insensitive* you can either call lowercase on the FileName and the TextBox eg `fn.ToLower().Contains(recetaTextBox.Text.ToLower())` or you can use pattern in the GetFiles eg `GetFiles(path, "*"+recetaTextBox.Text+"*.*")` because windows file naming is case insens . If you want exact, swap `Contains` for `Equals` – Caius Jard Oct 25 '21 at 07:06
  • I apply the change, works great. Thank you @CaiusJard, I appreciate your help. Just one last request, if the text input on the textbox doesn't match to any existing file to get a not file found message. – fjleon Oct 25 '21 at 07:27
  • I'm not sure how that would arise in the code I can see. Can you show the line it occurs on, what is the value of the TextBox and what is the full file path being processed at the time? – Caius Jard Oct 25 '21 at 09:18