-1

I run cmd.exe to move a file with Administrator rights:

ThisParams := '/C move ' + '"' + ThisSourceFile + '"' + ' ' + '"' + ATargetFile + '"';
Winapi.ShellAPI.ShellExecute(0, 'runas', 'cmd.exe', PChar(ThisParams), '', Winapi.Windows.SW_HIDE);

Unfortunately, ShellExecute always gives back success, regardless of whether the move action was successful or not (the move action would fail for example if the target file exists and it is read-only or if the target disk is write-protected).

So how can I get notified if the move action in the above case fails?

kobik
  • 21,001
  • 4
  • 61
  • 121
user1580348
  • 5,721
  • 4
  • 43
  • 105
  • You can't. `ShellExecute` launches the command interpreter. Clearly, that operation succeeds. `ShellExecute` cannot notify you about the outcome of operations launched on its behalf. You're going to have to look for another solution (like writing your own file-move program, and launching that instead). – IInspectable Jan 06 '20 at 14:45
  • 2
    You should stop trying to use `cmd.exe` to move files, and do that from your own code. I see that you are wanting to elevate, but you will need to address that issue another way. The `runas` verb isn't the right solution here. – David Heffernan Jan 06 '20 at 14:57
  • Couldn't I use `try-except`? What kind of error occurs if `MOVE` fails? OS error? Win32 error? – user1580348 Jan 06 '20 at 15:10
  • @DavidHeffernan The `runas` verb is used for another purpose, it has nothing to do with my question. – user1580348 Jan 06 '20 at 15:15
  • 1
    The `runas` verb is used to elevate. If you don't need to elevate you can just call the `MoveFile` API function to perform the move. – David Heffernan Jan 06 '20 at 15:37
  • 4
    use `CoGetObject` with `"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}"` for get elevated `IFileOperation` - it show uac promt if need. than use `IFileOperation` – RbMm Jan 06 '20 at 16:12
  • https://stackoverflow.com/a/3273064/505088 – David Heffernan Jan 06 '20 at 16:19
  • @DavidHeffernan Why do you still always downvote my questions? Is this an emotional issue? – user1580348 Jan 06 '20 at 21:31
  • Does the [`MoveFile`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefile) API work for you? – Rita Han Jan 07 '20 at 03:22
  • @RitaHan-MSFT I need to move the file with Administrator rights without the calling app having any, so the move action has to be performed by a different process because an app cannot elevate itself. – user1580348 Jan 07 '20 at 15:29
  • The link above shows you how to do it without explicitly invoking another process, using the COM elevation moniker. This works beautifully. – David Heffernan Jan 07 '20 at 20:52
  • Ok, got it. Have you checked the link as @David Heffernan pointed out. Feel free let me know if there is any issue. – Rita Han Jan 09 '20 at 01:49

1 Answers1

-3

Perhaps you can use pipes and the load generated file ex. move A.txt B.TXT >result.txt

procedure TForm1.Button1Click(Sender: TObject);
var
  stToDo: string;
  sl1 : TSTringList ;
  MyResult : boolean ;
begin
  stToDo := '/C move "C:\Users\awr\Desktop\D2\a.txt" "C:\Users\awr\Desktop\D2\b.txt" >C:\Users\awr\Desktop\D2\Result.txt';
  ShellExecute(Application.Handle, 'runas', 'cmd.exe' ,PChar(stToDo),'',  SW_HIDE);
  sl1 := TSTringList.create ;
  sl1.LoadFromFile('C:\Users\awr\Desktop\D2\Result.txt');
  MyResult := trim(sl1.text) <> '' ;
  sl1.Free ; 

If the move fail "result.txt" is empty