Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Autostart (https://www.delphipraxis.net/186896-autostart.html)

DelphiUser123 9. Okt 2015 11:42

Autostart
 
Liebe Delphi Freunde,

ich möchte eine Verknüpfung meines Programmes in den Autostart Ordner verschieben.
Und zwar automatisch und für beliebige Rechner und nicht manuell.

Dazu benötige ich den Pfad für Autostart (der bei jedem Rechner anders sein kann).
Meine Recherchen ergaben: SHGetKnownFolderPath muss ich benutzen und in Uses Shlobj hinzufügen.
Microsoft sagt:
Code:
HRESULT SHGetKnownFolderPath(
  _In_     REFKNOWNFOLDERID rfid,
  _In_     DWORD           dwFlags,
  _In_opt_ HANDLE          hToken,
  _Out_    PWSTR           *ppszPath
);
Nun schreibe ich in das erste Argument FOLDERID_Startup, jedoch meldet Delphi zu eben diesem: "undeklarierter Bezeichner". Fehlt in Uses noch etwas das ich einbinden muss oder was mache ich falsch?

Vielen Dank für Antworten.

mm1256 9. Okt 2015 11:54

AW: Autostart
 
Hallo,

hier findest du die Deklarationen: https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

nahpets 9. Okt 2015 12:17

AW: Autostart
 
Unter Delphi 7 komme ich so an den Autostartordner:
Delphi-Quellcode:
uses ShlObj;

...
var
  PIDL    : PItemIDList;
  InFolder : array[0..MAX_PATH] of Char;
begin
  SHGetSpecialFolderLocation(0, CSIDL_STARTMENU, PIDL);
  SHGetPathFromIDList(PIDL, InFolder);
  fStartMenu := inFolder;
  SHGetSpecialFolderLocation(0, CSIDL_APPDATA, PIDL);
  SHGetPathFromIDList(PIDL, InFolder);
  fLocalAppData := inFolder;
  SHGetSpecialFolderLocation(0, CSIDL_STARTUP, PIDL);
  SHGetPathFromIDList(PIDL, InFolder);
  fAutoStartMenu := inFolder;
end;

...

mm1256 9. Okt 2015 13:07

AW: Autostart
 
@nahpets Hat das einen besonderen Grund, warum du über die PItemIDList gehst?

Das ginge doch auch kürzer:

Delphi-Quellcode:
function MySHGetFolderPath(const CLSID: Cardinal): string;
var
  Puffer : array[0..MAX_PATH] of Char;
begin
  SHGetFolderPath(0, // Handle
                  CLSID,
                  0, // hToken
                  0, // dwFlags
                  puffer);
  Result := string(Puffer);
end;

nahpets 9. Okt 2015 13:21

AW: Autostart
 
Zitat:

Zitat von mm1256 (Beitrag 1318158)
@nahpets Hat das einen besonderen Grund, warum du über die PItemIDList gehst?

Nö, eigentlich nicht, das ist mal wieder so ein klassischer Fall von "Vererbung per Copy&Paste" ;-)

HolgerX 9. Okt 2015 17:45

AW: Autostart
 
Ein kleiner Hinweis

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Deshalb in neuen Progs

SHGetKnownFolderPath

statt

SHGetFolderPath

verwenden.. ;)

DelphiUser123 9. Okt 2015 18:11

AW: Autostart
 
HolgerX war auf derselben Webseite wie ich.
Die Funktion von mm1256 funktioniert zwar bei mir, Danke.
Aber ich hätte gerne ein modernes neues Programm, wobei ich wieder am Anfangsproblem wäre.

HolgerX 9. Okt 2015 19:13

AW: Autostart
 
Einfach selber definieren.

Delphi-Quellcode:
const
  FOLDERID_Startup              : TGUID = '{B97D20BB-F46A-4C97-BA10-5E3608430854}';

weitere GUIDs findest Du im Link von mm1256

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

Delphi kennt die Konstanten noch nicht, sind ja erst seit Windows Vista vorhanden ;)

Deshalb auch am besten auch dynamisch linken:

Delphi-Quellcode:
const
  SHELL32_DLL : String = 'SHELL32.DLL';

// Systemordner ab Vista ermitteln
// DYNAMISCHER FUNKTIONSIMPORT !!!
type
  TShGetKnownFolderPath = function(const rfid : TGUID;
                                   dwFlags : DWord;
                                   hToken : THandle;
                                   out ppszPath : PWideChar): HResult; stdcall;

{*** Systemordner ab Vista ermitteln ***}
function ShGetKnownFolderPath(const rfid: TGUID;
                              dwFlags: DWord;
                              hToken: THandle;
                              out ppszPath: PWideChar): HResult;
var
  DLL_Handle : THandle;
  DLL_ShGetKnownFolderPath : TShGetKnownFolderPath;
begin
  Result := 0;
  // Handle für die SHELL32.DLL erhalten
  DLL_Handle := LoadLibrary(PChar(SHELL32_DLL));
  // Wenn Handle vorhanden, Adressen der Funktionen ermitteln
  if DLL_Handle <> 0 then begin
    try
      // Adressen ermitteln
      @DLL_ShGetKnownFolderPath := GetProcAddress(DLL_Handle, 'SHGetKnownFolderPath');
      // Wurde SHGetKnownFolderPath in der DLL gefunden?
      if @DLL_ShGetKnownFolderPath <> nil then begin
        Result:= DLL_ShGetKnownFolderPath(rfid, dwFlags, hToken, ppszPath);
      end else begin
        RaiseLastOSError;
      end;
    finally
      FreeLibrary(DLL_Handle);
    end;
  end else begin
    RaiseLastOSError;
  end;
end;

mm1256 9. Okt 2015 19:22

AW: Autostart
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich hab mir mal die Arbeit gemacht, und alle KNOWNFOLDERID's zusammengefasst. Jetzt weiß ich ja, wofür es nützlich war :)

Anbei die .pas.

hathor 9. Okt 2015 19:26

AW: Autostart
 
Liste der Anhänge anzeigen (Anzahl: 2)
AUTOSTART geht auch anders - über die Registry:

Delphi-Quellcode:
uses
Registry;

function CreateAutorunEntry(const AName, AFilename: String; active: Boolean): Boolean;
var
 Reg: TRegistry;
begin
 Reg := TRegistry.create;
 try
     Reg.Rootkey:= HKEY_CURRENT_USER;
     Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', True);
     if active = true then
     Reg.WriteString(AName, AFilename)
     else
     Reg.DeleteValue(AName);
 finally
   Reg.Free;
   Result := true;
 end;
end;

Aufruf:
procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateAutorunEntry(Application.Title, ParamStr(0), TRUE);
end;
Test-Programm

Delphi-Quellcode:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Win.Registry, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    CheckBox1: TCheckBox;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function CreateAutorunEntry(const AName, AFilename: String; active: Boolean): Boolean;
var
 Reg: TRegistry;
begin
 Reg := TRegistry.create;
 try
     Reg.Rootkey:= HKEY_CURRENT_USER;
     Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', True);
     if active = true then
     Reg.WriteString(AName, AFilename)
     else
     Reg.DeleteValue(AName);
 finally
   Reg.Free;
   Result := true;
 end;
end;

// [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
function IsAutoRun : Boolean;
var Reg : TRegistry;
begin
 Reg := TRegistry.create;
 try
     Reg.Rootkey:= HKEY_CURRENT_USER;
     Reg.OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', True);
//     Form1.CheckBox1.Checked :=
     Result:= Reg.ValueExists(Application.Title);
 finally
   Reg.Free;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateAutorunEntry(Application.Title, ParamStr(0), TRUE);
   Sleep(1000); Winapi.Windows.Beep(1000,100); Winapi.Windows.Beep(2000,100);
   CheckBox1.Checked:= IsAutoRun;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  CheckBox1.Checked:= IsAutoRun;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
   CreateAutorunEntry(Application.Title, ParamStr(0), FALSE);
   Sleep(1000); Winapi.Windows.Beep(2000,100); Winapi.Windows.Beep(1000,100);
   CheckBox1.Checked:= IsAutoRun;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  Caption:= Application.Title;
  CheckBox1.Checked:= IsAutoRun;
end;

end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:18 Uhr.

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