Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Kopieren in UAC geschützte Verzeichnisse (https://www.delphipraxis.net/188738-kopieren-uac-geschuetzte-verzeichnisse.html)

ringli 1. Apr 2016 11:01

Kopieren in UAC geschützte Verzeichnisse
 
Ich experimentiere derzeit mit der Funktion CopyFileIFileOperationForceDirectories (hier gefunden).

Delphi-Quellcode:
uses ActiveX, ComObj, ShlObj;
 
function CopyFileIFileOperationForceDirectories(const srcFile, destFile : string) : boolean;
//works on Windows >= Vista and 2008 server
var
  r : HRESULT;
  fileOp: IFileOperation;
  siSrcFile: IShellItem;
  siDestFolder: IShellItem;
  destFileFolder, destFileName : string;
  pbc : IBindCtx;
  w32fd : TWin32FindData;
  ifs : TFileSystemBindData;
begin
  result := false;
 
  destFileFolder := ExtractFileDir(destFile);
  destFileName := ExtractFileName(destFile);
 
  //init com
  r := CoInitializeEx(nil, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE);
  if Succeeded(r) then
  begin
    //create IFileOperation interface
    r := CoCreateInstance(CLSID_FileOperation, nil, CLSCTX_ALL, IFileOperation, fileOp);
    if Succeeded(r) then
    begin
      //set operations flags
      r := fileOp.SetOperationFlags(FOF_NOCONFIRMATION OR FOFX_NOMINIMIZEBOX OR FOF_NOCONFIRMMKDIR);
      if Succeeded(r) then
      begin
        //get source shell item
        r := SHCreateItemFromParsingName(PChar(srcFile), nil, IShellItem, siSrcFile);
        if Succeeded(r) then
        begin
          //create binding context to pretend there is a folder there
          if NOT DirectoryExists(destFileFolder) then
          begin
            ZeroMemory(@w32fd, Sizeof(TWin32FindData));
            w32fd.dwFileAttributes := FILE_ATTRIBUTE_DIRECTORY;
            ifs := TFileSystemBindData.Create;
            ifs.SetFindData(w32fd);
            r := CreateBindCtx(0, pbc);
            r := pbc.RegisterObjectParam(STR_FILE_SYS_BIND_DATA, ifs);
          end
          else
            pbc := nil;
 
          //get destination folder shell item
          r := SHCreateItemFromParsingName(PChar(destFileFolder), pbc, IShellItem, siDestFolder);
 
          //add copy operation
          if Succeeded(r) then r := fileOp.CopyItem(siSrcFile, siDestFolder, PChar(destFileName), nil);
        end;
 
        //execute
        if Succeeded(r) then r := fileOp.PerformOperations;
 
        result := Succeeded(r);
 
        OleCheck(r);
      end;
    end;
 
    CoUninitialize;
  end;
end;
Kopiere ich Dateien in nicht UAC geschützte Verzeichnisse (z.B. "D:\Test\1\2\3") wird ein angegebenes Zielverzeichnis problemlos erstellt wenn es nicht vorhanden ist. Also so wie es der Funktionsname erahnen lässt.

In UAC geschützte Verzeichnisse (z.B. "C:\program files") kann ich nach Bestätigung des UAC-Dialoges ebenfalls Dateien kopieren. Allerdings funktioniert das nur wenn das Zielverzeichnis bereits existiert. Sobald ein angegebenes Zielverzeichnis erstellt werden muss, schlägt die Funktion mit der Meldung "OLE-Fehler 80270022" fehl.

Hat jemand eine Idee wie man das Problem lösen kann?

p80286 1. Apr 2016 11:45

AW: Kopieren in UAC geschützte Verzeichnisse
 
Du bist Dir sicher, daß der Fehlercode richtig ist?

Gruß
K-H

ringli 1. Apr 2016 12:00

AW: Kopieren in UAC geschützte Verzeichnisse
 
Ja, das ist der Fehler der mir angezeigt wird wenn ich die Funktion folgendermaßen aufrufe:

Delphi-Quellcode:
CopyFileIFileOperationForceDirectories('E:\Test 1\Test 2\Test 3\test.txt', 'c:\program files\Test\test.txt');

t.roller 1. Apr 2016 12:58

AW: Kopieren in UAC geschützte Verzeichnisse
 
Dein Programm braucht Administrator-Rechte.

ringli 1. Apr 2016 13:17

AW: Kopieren in UAC geschützte Verzeichnisse
 
Die Routine fordert beim Kopieren in UAC geschützte Verzeichnisse die entsprechenden Rechte an. Das funktioniert problemlos solange das Zielverzeichnis existiert. Nur wenn das/die Zielverzeichniss(e) erst noch erstellt werden müssen funktioniert die Anforderung der Rechte nicht.

Das Programm soll erst bei Bedarf die entsprechenden Rechte anfordern und nicht von vornherein mit Admin-Rechten laufen.

t.roller 28. Aug 2016 16:46

AW: Kopieren in UAC geschützte Verzeichnisse
 
Delphi-Quellcode:
//create IFileOperation interface
  r := CoCreateInstanceAsAdmin(Self.Handle, CLSID_FileOperation, IFileOperation, @lFileOp);
http://www.codenewsfast.com/cnf/arti...art-ng1925q704

Pixel 31. Aug 2016 11:27

AW: Kopieren in UAC geschützte Verzeichnisse
 
Hey,

wenn du nicht unbedingt darauf pochst das so umsetzen zu wollen, dann spar dir doch den ganzen Ärger und fordere einfach beim Programmstart direkt Adminrechte an.

http://stackoverflow.com/questions/1...rights-request

Kannst du dort copy&pasten - ist ein Manifest.

Dann hast du die Fehler die du jetzt hast und Fehler die du vlt. noch gar nicht kennst auf einmal beseitigt ;)

p80286 31. Aug 2016 11:49

AW: Kopieren in UAC geschützte Verzeichnisse
 
Zitat:

Zitat von ringli (Beitrag 1334458)
Nur wenn das/die Zielverzeichniss(e) erst noch erstellt werden müssen funktioniert die Anforderung der Rechte nicht.

Welcher Rechte? Wenn es das Verzeichnis noch nicht gibt, erbt es zunächst einmal vom übergeordneten Verzeichnis. Was übrigens auch für Dateien gilt.
Etwas anders ist es wenn Du Dateien oder ganze Verzeichnisse verschiebst, dann kommen die Rechte mit.

Zitat:

Zitat von ringli (Beitrag 1334458)
Das Programm soll erst bei Bedarf die entsprechenden Rechte anfordern

:thumb:
Zitat:

Zitat von ringli (Beitrag 1334458)
..und nicht von vornherein mit Admin-Rechten laufen.

Wobei es ja fraglich ist, ob der sog. Admin überhaupt die entsprechende Berechtigung hat.

Gruß
K-H

t.roller 31. Aug 2016 19:35

AW: Kopieren in UAC geschützte Verzeichnisse
 
OLE-Fehler 80270022, // Security problem on destination

ringli 3. Sep 2016 13:42

AW: Kopieren in UAC geschützte Verzeichnisse
 
Zitat:

Zitat von t.roller (Beitrag 1346005)
Delphi-Quellcode:
//create IFileOperation interface
r := CoCreateInstanceAsAdmin(Self.Handle, CLSID_FileOperation, IFileOperation, @lFileOp);

Vielen Dank für deine Hilfe. Damit und mit dem bereits gezeigten Code kann ich mir hoffentlich was brauchbares zusammenstricken damit die Schreibrechte nur bei Bedarf angefordert werden. :)

Zitat:

Zitat von Pixel (Beitrag 1346327)
Hey, wenn du nicht unbedingt darauf pochst das so umsetzen zu wollen, dann spar dir doch den ganzen Ärger und fordere einfach beim Programmstart direkt Adminrechte an.

Keine gute Idee. Ich mag es selber nicht wenn Programme immer mit Adminrechten laufen wollen, zumal es meistens auch nur in Ausnahmefällen nötig ist.

Zitat:

Zitat von p80286 (Beitrag 1346330)
Welcher Rechte?

Die Schreibrechte für das Zielverzeichnis meinte ich.

t.roller 3. Sep 2016 16:29

AW: Kopieren in UAC geschützte Verzeichnisse
 
Der Code in #1 funktioniert bei mir (WIN8.1, XE7) ohne Änderung.

HINWEIS:
Beispiel:
Wenn "C:\Windows\System32\ATEST\123Test" erzeugt werden soll,
ist das Ergebnis bei
64Bit
C:\Windows\System32\ATEST\123Test
32Bit
C:\Windows\SysWOW64\ATEST\123Test

ringli 3. Sep 2016 17:59

AW: Kopieren in UAC geschützte Verzeichnisse
 
Du hast aber nicht zufällig administrative Rechte bei deinem Benutzerkonto? Hast du auch mal versucht nach "C:\Program Files" Dateien zu kopieren?

Ich habe hier WIN 10 (x64) und XE4, keine Ahnung ob es bei dem in #1 gezeigten Code zu Unterschieden beim Kompilieren kommt. :?

t.roller 3. Sep 2016 19:28

AW: Kopieren in UAC geschützte Verzeichnisse
 
Mit dem Compilieren hat das nichts zu tun.
UAC verhält sich in WIN10 restriktiver als in WIN8.1.
WIN10:
"C:\Program Files" ist im Explorer "C:\Programme".

In C:\Windows\System32\... kann ich ohne Administrator-Rechte nichts erstellen oder kopieren. Das gilt für die 32Bit- und 64Bit-Version.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz