/ShellStuff_win.pas

http://github.com/foxblock/PNDTools · Pascal · 121 lines · 83 code · 14 blank · 24 comment · 9 complexity · f08780490abc337cb238b2a4637ee6cc MD5 · raw file

  1. unit ShellStuff_win;
  2. interface
  3. uses Windows;
  4. { Copies a list of files (separated by #0) from ASource to ADest, both strings
  5. must contain the same number of files
  6. Will rename the copied file if ARenameCheck is true, replace otherwise
  7. Will never ask for rename or rewrite action
  8. Creates new directories if necessary
  9. Displays the OS copy dialogue
  10. Returns true on success, false otherwuse, use GetLastError for details in the
  11. latter case }
  12. function ShellCopyFile(const ASource, ADest: String; ARenameCheck: Boolean = false): Boolean;
  13. { Deletes a file, a folder or a list of both (separated by #0)
  14. Is silent (does not display OS delete dialogue) and does not move to trash
  15. Returns true on success, false otherwuse, use GetLastError for details in the
  16. latter case }
  17. function ShellDeleteFile(FileName : String): Boolean;
  18. { Executes program FileName in ExeDir and passes parameters Params
  19. ExeDir defaults to the directory this application is in
  20. Verb can be changed for non-binary files to 'open' or 'explore' for example,
  21. see the ShellAPI documentation for more info
  22. If WaitForFinish is true the function will not return until the executed
  23. process has been terminated (is finished)
  24. Returns true on success, false otherwise, use GetLastError for details in the
  25. latter case }
  26. function ExecuteProgram(const FileName : String; const Params : String;
  27. const ExecDir : String = ''; const Verb : String = 'runas';
  28. const WaitForFinish : Boolean = true) : Boolean;
  29. { Tries to convert a DOS path into a POSIX path used by Cygwin applications
  30. The Linux version should simply return Path or convert any '\' to '/' }
  31. function ConvertPath(const Path : String) : String;
  32. implementation
  33. uses ShellAPI, Forms, SysUtils;
  34. function ShellCopyFile(const ASource, ADest: String; ARenameCheck: Boolean = false): Boolean;
  35. var
  36. sh: TSHFileOpStruct;
  37. begin
  38. sh.Wnd := Application.Handle;
  39. sh.wFunc := FO_COPY;
  40. // String has to be terminated with #0#0
  41. sh.pFrom := PChar(ASource + #0);
  42. sh.pTo := PChar(ADest + #0);
  43. sh.fFlags := FOF_MULTIDESTFILES or FOF_NOCONFIRMATION or FOF_NOCONFIRMMKDIR;
  44. if ARenameCheck then
  45. sh.fFlags := sh.fFlags or FOF_RENAMEONCOLLISION;
  46. Result := (ShFileOperation(sh) = 0);
  47. end;
  48. function ShellDeleteFile(FileName : String): Boolean;
  49. var
  50. sh: TSHFileOpStruct;
  51. begin
  52. sh.Wnd := Application.Handle;
  53. sh.wFunc := FO_DELETE;
  54. sh.fFlags := FOF_SILENT OR FOF_NOCONFIRMATION;
  55. sh.pFrom := PChar(FileName + #0);
  56. sh.pTo := #0;
  57. Result := (ShFileOperation(sh) = 0);
  58. end;
  59. function ExecuteProgram(const FileName : String; const Params : String;
  60. const ExecDir : String = ''; const Verb : String = 'runas';
  61. const WaitForFinish : Boolean = true) : Boolean;
  62. var
  63. ShExecInfo : SHELLEXECUTEINFO;
  64. ExitCode : Cardinal;
  65. OSInfo : OSVERSIONINFO;
  66. begin
  67. // Get Windows version to switch between 'runas' and 'open' verb
  68. GetVersionEx(OSInfo);
  69. ShExecInfo.Wnd := Application.Handle;
  70. ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  71. ShExecInfo.cbSize := SizeOf(SHELLEXECUTEINFOW);
  72. if (Verb = 'runas') AND ((OSInfo.dwMajorVersion < 6) // XP and older
  73. OR (ExtractFileExt(FileName) <> 'exe')) then // only use 'runas' on .exe (won't work for .bat)
  74. ShExecInfo.lpVerb := PChar('open')
  75. else
  76. ShExecInfo.lpVerb := PChar(Verb);
  77. ShExecInfo.lpFile := PChar(FileName);
  78. ShExecInfo.lpParameters := PChar(Params);
  79. if ExecDir = '' then
  80. ShExecInfo.lpDirectory := PChar(ExtractFileDir(Application.ExeName))
  81. else
  82. ShExecInfo.lpDirectory := PChar(ExecDir);
  83. ShExecInfo.nShow := SW_SHOW;
  84. Result := ShellExecuteEx(@ShExecInfo);
  85. if WaitForFinish AND Result then
  86. begin
  87. ExitCode := STILL_ACTIVE;
  88. repeat
  89. GetExitCodeProcess(ShExecInfo.hProcess,ExitCode); //while the process is running
  90. until (ExitCode <> STILL_ACTIVE);
  91. end;
  92. end;
  93. function ConvertPath(const Path : String) : String;
  94. var
  95. Drive : String;
  96. begin
  97. Drive := ExtractFileDrive(Path);
  98. Result := Path;
  99. if Length(Drive) > 1 then
  100. begin
  101. Result := StringReplace(Result,Drive,'',[]);
  102. Result := 'cygdrive/' + Drive[1] + Result;
  103. end;
  104. Result := StringReplace(Result,'\','/',[rfReplaceAll]);
  105. end;
  106. end.