3

I've been working on getting this right for a few hours now, and it works perfectly on Windows Vista & Windows 7, but when I run it on Windows XP it fails without any message. Unfortunately I don't have a development environment under XP so I can't just run it through a debugger to check, have I missed something blindingly obvious? The same piece of code does actually use a CopyFile and a few commands to write out data to C:\ so if it's a permissions error it's an odd one.

EDIT: The return value is 1223, ERROR_CANCELLED which means cancelled by user.

EDIT 2: I disabled the s.fFlags and it immediately popped a dialog box up asking if it should create the dir-test folder, so I switched to FOF_NOCONFIRMATION and it appeared to ignore the flag. I do also use that during a deletion using the same SHFileOperation method so it either doesn't apply to file copies.

LPTSTR source = L"dir-test\\*\0";               
LPTSTR dest = L"C:\\dir-test\0";


SHFILEOPSTRUCT s = { 0 };
s.hwnd = 0;
s.wFunc = FO_COPY;
s.fFlags = FOF_SILENT;
s.pTo = dest;
s.pFrom = source;
int n;
n = SHFileOperation(&s);`
Nicholas Smith
  • 11,642
  • 6
  • 37
  • 55
  • 3
    What is the return value? – lcs Mar 06 '13 at 15:28
  • 1
    Why don't you use [`MoveFile`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365239(v=vs.85).aspx)? – bash.d Mar 06 '13 at 15:30
  • @millsj: couldn't tell you, I don't have an XP dev environment to debug it. – Nicholas Smith Mar 06 '13 at 15:32
  • @bash.d: well, `MoveFile` moves, and I need a copy instead, unless I've missed an option to `MoveFile` that leaves the original in place. – Nicholas Smith Mar 06 '13 at 15:33
  • @bash.d: oh, and `MoveFile` doesn't work across drives which is something I need to have. – Nicholas Smith Mar 06 '13 at 15:34
  • @NicholasSmith my bad, sorry. What about [`CopyFileEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa363852(v=vs.85).aspx) instead? – bash.d Mar 06 '13 at 15:35
  • 3
    You're assigning the return value to a variable but not checking it for an error? Seems like that should be the first step and wouldn't need a dev environment, just display a message if you get an error, then at least you can track it from there. – Roger Rowland Mar 06 '13 at 15:36
  • @bash.d: Does `CopyFileEx` preserve directory structure? If it does I'd be very, very happy but so far `SHFileOperation` is the only thing I've come across that does directory copies. – Nicholas Smith Mar 06 '13 at 15:37
  • @roger_rowland: oddly I was using it for debug purposes but didn't have a window attached, so I could add an error box in but I was hoping I'd missed something simple before I need to rebuild it and redeploy onto an XP machine. – Nicholas Smith Mar 06 '13 at 15:38
  • Well, I am not sure... It's the only function I know from there... – bash.d Mar 06 '13 at 15:38
  • 1
    @Nicholas Smith - "but I was hoping I'd missed something simple" ... like checking the return code? ;-) – Roger Rowland Mar 06 '13 at 15:46
  • @roger_rowland: like a "MAKE_THIS_WORK_XP" option flag. – Nicholas Smith Mar 06 '13 at 15:47
  • lol - if you find one, let me know! – Roger Rowland Mar 06 '13 at 15:48
  • I didn't, but it's throwing `1223` as an error so it gives me a starting point. – Nicholas Smith Mar 06 '13 at 15:48
  • One more thing from a comment on MSDN - pFrom and pTo are *lists* of strings, so need to be terminated with TWO \0 characters, not one. [EDIT] - ok, I see you did that, sorry! – Roger Rowland Mar 06 '13 at 15:51
  • Ah unless you use the LPTSTR then Microsoft's documentation recommends the single `\0` at the end as the `LPTSTR` already adds a null for you. It is however, excellently bad documentation so anyone could be right. – Nicholas Smith Mar 06 '13 at 15:53

2 Answers2

1

So it turns out for some odd reason that using the SHFileOperation will force a confirm dialog for Windows XP (but not Vista or 7) and ignore the flags to tell it to just confirm. Simple fix of using CreateDirectory() prior to running the copy, which doesn't require a confirmation dialog.

Nicholas Smith
  • 11,642
  • 6
  • 37
  • 55
0

The documentation for SHFILEOPSTRUCT has this warning:

It cannot be overstated that your paths should always be full paths. If the pFrom or pTo members are unqualified names, the current directories are taken from the global current drive and directory settings as managed by the GetCurrentDirectory and SetCurrentDirectory functions.

Your source specification is an unqualified name.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • True, but I'm moving the files from the current directory the application is executing out of, and whilst I could ask Windows to provide the fully qualified path to it it's not actually causing a problem. – Nicholas Smith Mar 06 '13 at 16:02
  • 1
    @NicholasSmith ... And you're sure you haven't done something like opened a file dialog which could change the current directory in one OS but not the other? http://stackoverflow.com/questions/930816/why-does-openfiledialog-change-my-working-directory – Roddy Mar 06 '13 at 16:34