Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Konkretes Verzeichnis suchen und Pfad verwenden (https://www.delphipraxis.net/165841-konkretes-verzeichnis-suchen-und-pfad-verwenden.html)

jaenicke 24. Jan 2012 06:00

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Zitat:

Zitat von Elexarie (Beitrag 1147322)
Jetzt geht es daran, dass ich den relativen Pfad in meinem Programmordner in den bestehenden Pfad kopieren und notfalls ersetzen will!

Und wo ist da dein Problem? Dateien suchen kannst du ja offenbar schon. Suchst du ForceDirectories um das Zielverzeichnis ggf. anzulegen?

Dann noch zwei allgemeine Punkte:
Denke dran, dass eine relative Verzeichnisangabe "data" oder so nicht auf das Unterverzeichnis deiner Exe zeigt, sondern auf das Arbeitsverzeichnis. Wenn du ein Unterverzeichnis im Verzeichnis deiner Exe ansprechen willst, musst du auch den Pfad aus ParamStr(0) dafür benutzen.

Wenn du in das Verzeichnis eines Programms Daten kopieren willst, brauchst du Adminrechte. Die musst du also vorher anfordern. Entweder bereits beim Start der Exe per Manifest oder sobald du sie zum Kopieren benötigst.

Elexarie 24. Jan 2012 17:16

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Hallo und vielen Dank für die Bemerkungen.

Ich habe das Manifest erstellt:

Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <v3:trustInfo xmlns:v3="urn:schemas-microsoft-com:asm.v3">
    <v3:security>
      <v3:requestedPrivileges>
        <v3:requestedExecutionLevel level="highestAvailable" />
      </v3:requestedPrivileges>
    </v3:security>
  </v3:trustInfo>
</assembly>
Es hat auch alles soweit geklappt. Ist es normal, dass ich keine UAC - Anfrage erhalte? Also, ich erkenne nicht, ob es jetzt ein Programm ist, was Adminrechte erfordert. Normalerweise erhält man ja die Anzeige.

jaenicke 24. Jan 2012 17:38

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Naja, bei requestedExecutionLevel hast du ja geschrieben highestAvailable, also die höchsten Rechte, die der aktuelle Benutzer hat. Du wolltest aber ja wohl eigentlich eher requireAdministrator, oder? ;-)

Elexarie 24. Jan 2012 17:56

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Gibt sich aber kein Unterschied, denn ich bekomme noch immer kein UAC. :S

Also nochmal zusammenfassend:

Project1.rc:

Code:
1 24 "Project1.exe.manifest"
Project1.exe.manifest

Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <v3:trustInfo xmlns:v3="urn:schemas-microsoft-com:asm.v3">
    <v3:security>
      <v3:requestedPrivileges>
        <v3:requestedExecutionLevel level="requireAdministrator" />
      </v3:requestedPrivileges>
    </v3:security>
  </v3:trustInfo>
</assembly>
Und dann erstelle ich das über den Delphi Compiler und habe dann die Project1.res und diese nenne ich in manifest.res.

Ich binde es über
Code:
{$R manifest.res}
ein.

Was ist der Fehler?

Elexarie 24. Jan 2012 18:02

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Okay. Es klappt alles! :)

Welche Funktionen (schmeißt mal welche in den Raum) könnten jetzt für das Ordner kopieren / einfügen dienlich sein.

Elexarie 24. Jan 2012 21:39

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Weiter ging es. Habe jetzt geschätzte 4 - 5 Stunden an dem Verschieben gesessen. Verschiedene Methoden verwendet und bin am Ende an diesem Code stehengeblieben, weil hier die Datenträger egal sind.

Delphi-Quellcode:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IDGLobal, GIFImg, ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Label1: TLabel;
    Image1: TImage;
    Button1: TButton;
    Image2: TImage;
    Label2: TLabel;
    Edit2: TEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  path: String;
  destPath: TStrings;
implementation

{$R *.dfm}


uses Registry, ShellAPI;


function DoFileWork(
  aWnd: HWND; aOperation: UINT; aFrom, aTo: TStrings; aFlags: FILEOP_FLAGS
  ): Integer;
var
  I: Integer;
  FromPath, ToPath: string;
  SHFileOpStruct: TSHFileOpStruct;
begin
  FromPath := '';
  for I := 0 to aFrom.Count - 1 do
    FromPath := FromPath + aFrom.Strings[I] + #0;
  FromPath := FromPath + #0;

  if Assigned(aTo) then
  begin
    ToPath := '';
    for I := 0 to aTo.Count - 1 do
      ToPath := ToPath + aTo.Strings[I] + #0;
    ToPath := ToPath + #0;
    if aTo.Count > 0 then
      aFlags := aFlags or FOF_MULTIDESTFILES;
  end;

  with SHFileOpStruct do
  begin
    Wnd := aWnd;
    wFunc := aOperation;
    pFrom := PChar(FromPath);
    if Assigned(aTo) then
    begin
      pTo := PChar(ToPath)
    end else begin
      pTo := nil;
    end;
    fFlags := aFlags;
  end;
  Result := SHFileOperation(SHFileOpStruct);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  steamname: string;
  regist: TRegistry;


begin

  regist := TRegistry.Create();
  try
    regist.RootKey := HKEY_LOCAL_MACHINE;
    regist.OpenKey('Software\Valve\Steam', true);
    path := regist.ReadString('InstallPath');

  finally
    regist.Free;
  end;

  steamname := Edit1.Text;
  if steamname = '' then
  begin
    ShowMessage('Steamname ist leer');
    Exit;
  end;
  Edit2.Text := path + '\SteamApps\' + steamname +
    '\counter-strike source\cstrike';


  DestPath.Add(Edit2.Text);

  Image1.Visible := false;
  Image2.Visible := true;

end;



procedure TForm1.Button2Click(Sender: TObject);
var rootPath : TStrings; preRootPath : string;


begin
path := Edit2.Text;
  if MessageDlg(
    'Configdatein wirklich übertragen. Bereits vorhandene Daten werden überschrieben'
      , mtConfirmation, mbYesNo, 0) = mrYes
      then
         begin

         preRootPath := ParamStr(0) + '\install\maps';


         rootPath.Add(preRootPath);

         DoFileWork(Self.Handle, FO_MOVE, rootPath, destPath,FOF_NOCONFIRMATION );
         rootPath.Free;
         destPath.Free;

         end;



end;

end.
Ich bekomme Zugriffsverletzungen und von der Korrektheit bin ich auch noch nicht überzeugt. Mein kläglicher Versuch TStrings zu erstellen gefällt mir auch nicht. Habt ihr Vorschläge, wie meine Funktionalität gewährleistet wäre?

himitsu 24. Jan 2012 21:57

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Wo ist der Fehler?
Warum ist DestPath eine globale Variable?
Wo erstellst du DestPath?
...

Ansonsten empfehle ich die Verwendung des Debuggers ... man glaubt es kaum, aber bei der Auffindung derartiger Fehler ist sowas extrem hilfreich.

Elexarie 24. Jan 2012 22:01

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
DestPath ist global, da ich ihn in beiden Funktionen brauche. Die DestPath entspricht dem Edit2.Text, da dort überprüft werden soll, ob das mit dem Ort hinkommt.

Müsste DestPath über Destpath.Create erst konstruiert werden?

Sir Rufo 24. Jan 2012 22:26

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Destpath ist nur eine Referenz auf eine Instanz - somit also nur ein Zeiger auf einen Speicherbereich ...
Des weiteren ist Destpath vom Typ TStrings und das ist eine abstrakte Klasse, davon kann man keine Instanz erzeugen, sondern nur von einer abgeleiteten Klasse (z.B. TStringList).

Das Erzeugen einer Instanz erfolgt über die konkrete Klasse (in diesem Beispiel):
Delphi-Quellcode:
DestPath := TStringList.Create;
Du hast da auch noch eine Variable rootPath, auch hier hast du vergessen eine Instanz anzulegen.

Anscheinend bist du noch nicht so firm in Delphi/Programmieren, und daher wundert es mich, warum du auf so einen API-Konstrukt zurückgreifst und dann auch noch eine Übergabe von TStrings verwendest, wo du doch nur einen Quell- und Ziel-Pfad benötigst.

Ja es sieht nach CopyPaste aus ... ich weiß nicht, ob du dir damit einen Gefallen getan hast ...

EDIT: Wenn du Delphi2010 und höher einsetzt, dann kannst du dir auch mal die Unit Delphi-Referenz durchsuchenioutils anschauen, da ist so einiges zum Thema Delphi-Referenz durchsuchenTFile, Delphi-Referenz durchsuchenTDirectory und Delphi-Referenz durchsuchenTPath zu finden, was dir evtl. helfen könnte.
Wäre auch schön, wenn du dein Profil um diese Angaben (welche Delphi Version setzt du ein) ergänzen könntest

Bjoerk 25. Jan 2012 00:15

AW: Konkretes Verzeichnis suchen und Pfad verwenden
 
Da hast du dir mit FOF_MULTIDESTFILES eine sehr komplizierte Variante von DoFileWork ausgesucht. Benutzt man eigentlich nur, wenn die Zielpfade unterschiedlich sind.

Wenn‘s unbedingt analog DoFileWork sein, dann eher so:

Delphi-Quellcode:
function CopyPath(const AFrom, ATo: string): boolean;
var
  SHFileOpStruct: TSHFileOpStruct;
begin
  with SHFileOpStruct do
  begin
    Wnd:= Application.Handle;
    wFunc:= FO_COPY; // FO_MOVE für verschieben
    pFrom:= PChar(AFrom + #0 + #0);
    pTo:= PChar(ATo + #0 + #0);
    // fFlags:= FOF_NOCONFIRMATION or FOF_SILENT;
  end;
  Result:= SHFileOperation(SHFileOpStruct) = 0;
end;
Diese Routine kopiert eine Datei oder ein Verzeichneis in das Verzeichnis ATo. rootPath und destPath wären dann jetzt also strings.

Delphi-Quellcode:
  if CopyPath(rootPath, destPath) then ShowMessage ('jepp');


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:40 Uhr.
Seite 2 von 3     12 3      

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