Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Programmstart durch Autostart - kann man das herausfinden? (https://www.delphipraxis.net/77166-programmstart-durch-autostart-kann-man-das-herausfinden.html)

Flare 15. Sep 2006 14:20


Programmstart durch Autostart - kann man das herausfinden?
 
Hallo DP!

Ich habe mal eine Frage zum Thema Windows-Start und Autostart.

Wenn ich zum Beispiel die Programme ICQ Lite und den Windows Messenger habe (ich habe noch ein paar mehr Beispiele aber 2 dürften reichen), dann liegen die ja auf Wunsch im Autostart von Windows - In der Registry eingetragen.
Damit man den Autostart besser vom normalen Start unterscheiden konnte wurden entsprechende Parameter zum Starten angehängt.

Und jetzt das Problem bzw. meine Frage:

Kann man herausfinden ob ein Programm direkt beim Systemstart gestartet wird (also durch das durchgehen aller Autostarts von Windows) oder erst danach?

Bei mir ist es nämlich so, ich kann ICQ und MSN nicht mit dem Parameter manuell starten, es klappt bloß wenn der Parameter weg ist.

Flare

Martin K 15. Sep 2006 14:31

Re: Programmstart durch Autostart - kann man das herausfinde
 
Du meinst, Du willst wissen, welche Programme alle im Autostart von Windows liegen?

Das sind folgende Schlüssel in der Registry:
HKCU\Software\Microsoft\Windows\CurrentVersion\Run (für den aktuellen Benutzer)
HKLM\Software\Microsoft\Windows\CurrentVersion\Run (für alle Benutzer)

oder im Startmenü:
Start -> Programme -> Autostart

Aber ich habe dazu auch mal ein Programm geschrieben:
http://www.delphipraxis.net/internal...ct.php?t=85450

Nachtrag:
Du kannst auch im Startmenü: Start -> Ausführen
msconfig
eingeben und dann auf "Systemstart" klicken.

Flare 15. Sep 2006 14:36

Re: Programmstart durch Autostart - kann man das herausfinde
 
Nein, ich möchte herausfinden OB man herausfinden kann OB ein Programm durch den Windows Autostart gestartet wurde oder nicht, das scheint nämlich ICQ und MSN zu können...

Wo alle möglichen Autostarts liegen weiß ich schon :drunken:


Flare

P.S.: Ich habe elber dazu ein Programm geschrieben :stupid:

Go2EITS 15. Sep 2006 14:42

Re: Programmstart durch Autostart - kann man das herausfinde
 
Also normale Programme wie ICQ etc. werden über die Autostart gestartet.

Sogenannte Dienste (sagen wir mal das sind "Spezialprogramme") werden nach dem Booten des Betiebssystems und VOR dem Laden der Programme in der Autostart ausgeführt.

Über z. B.
Delphi-Quellcode:
Uses registry...
function IsAppInRun(RunName: string): Boolean;
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create;
  with Reg do
  begin
    RootKey := HKEY_LOCAL_MACHINE;
    OpenKey('Software\Microsoft\Windows\CurrentVersion\Run', False);
    Result := ValueExists(RunName);
    CloseKey;
    Free;
  end;
end;
Kannst Du prüfen ob ein Programm in der Registry steht. Dazu musst Du aber den Runnamen rausfinden.
Nimm dazu Regedit.
Weitere Codes dazu hier:
Torry hilft!

Roter Kasten:
Sorry, aber wenn in der Autorun das Programm steht, wird es auch ausgeführt.
Eine Routine, um zu prüfen ob Autostart(Programmname)=True ist, gibt es nicht. Du kannst nur nachsehen, ob das Programm in der Registry und RUN steht.

CU!
Go2EITS

Martin K 15. Sep 2006 14:43

Re: Programmstart durch Autostart - kann man das herausfinde
 
Sorry, dann hab ich Dich falsch verstanden....
Aber wenn das Programm gestartet ist und Du es nicht manuell gestartet hast und es auch im Autostart steht, dann wurde es wohl durch den Autostart von Windows gestartet :wink:

Zusätzliche Parameter beim Autostart sind nicht unbedingt erforderlich, meißtens werden die halt übergeben, damit das Programmm minimiert im Systray gestartet wird und nicht als sichtbares Fenster.
Bei einem eigenen Programm kannst Du die Parameter per ParamStr() auslesen, nicht aber ob es durch den Autostart oder irgendwie anders gestartet wurde - zumindest meines Wissens nach...
:roll:

Flare 15. Sep 2006 15:10

Re: Programmstart durch Autostart - kann man das herausfinde
 
Coole Sache, dass ich hier nur zur Hälfte verstanden werde, aber wenigstens hat Martin K eine Antwort gesagt die ich mir auch schon dachte.

Aber das ganze nochmal ganz deutlich!

Ich habe ein Programm programmiert womit man Auostarts von Windows extrahieren kann und mit meinem Programm danach (irgendwann später) starten kann. Allerdings startet er die Programme manchmal nicht, was mit dem Parameter zu tun hat. Also immer die selben Programme starten nicht, manche jedoch starten.

Die Idee die angebracht wurde ist, dass das Programm nachguckt ob es im Autostart steht wenn es per speziellem Parameter gestartet wird und beendet sich wieder falls dem nicht so ist.

Kann das jemand bestätigen oder gibts da nen noch einfacheren Trick den ich nicht kenne?


Flare

Martin K 15. Sep 2006 15:17

Re: Programmstart durch Autostart - kann man das herausfinde
 
Wenn Du mit deinem Programm ein Programm startest was im Autostart steht, startest Du es dann mit den selben Parametern, die auch im Autostart stehen?
1. Möglicherweise läuft das Programm vorher noch und es verhindert von sich aus, dass das Programm selbst 2x gestartet wird
2. wenn Du es startest mit den Parametern wie im Autostart, siehst Du vielleicht gar nicht dass es gestartet wurde, weil es versteckt ist

Schau mal im Taskmanager unter "Prozesse", ob dort die exe von dem entsprechenden Programm aufgelistet ist, also ob:
1. es schon vorher läuft, bevor Du es mit deinem Programm startest
2. es gestartet wurde mit deinem Programm, nur halt versteckt

Go2EITS 15. Sep 2006 15:22

Re: Programmstart durch Autostart - kann man das herausfinde
 
Einige Programme starten auch nicht wenn Du die Parameter übergibst, genauso wie Programme, die keine Parameter benötigen.

Das könnte daran liegen, dass einige Programme ihren eigenen Path abfragen, daher starten die Programme nicht (weil Du aus einem anderen Verzeichnis startest, wohl mit shellexecute, in dem nicht die zum Programm gehörigen Dateien liegen) oder stürzen sogar ab, wenn sie Dateien beim Start abfragen, repektive einlesen wollen, die dann aber nicht zu finden sind.

Flare 15. Sep 2006 15:23

Re: Programmstart durch Autostart - kann man das herausfinde
 
Es wurde nicht gestartet (ich überwache natürlich alle Autostarts außer die System-notwendigen und den Ordner, aber da steht ICQ und MSN nunmal nicht drin :drunken:
Im Taskmanager gucke ich natürlich auch immer rein, es ist davor nicht gestartet und danach auch nicht.

Versteckt laufen sollten die Programme nicht (wieso sollte ICQ dies tun :gruebel: )

Ich starte es mit den selben Parametern (es gibt auch die Funktion die Atostarts wieder zurückzuschieben, dann muss ja auch die Kompatiblität geleistet sein)

Die Programme starten wobald ich den Parameter weglasse (mit ICQ und MSN getestet)


Flare

Martin K 15. Sep 2006 15:27

Re: Programmstart durch Autostart - kann man das herausfinde
 
Schreib doch einfach mal ein eigenes Programm in den Autostart und lass dir in dem Programm das Verzeichnis mit GetCurrentDir anzeigen.
Dann weißt Du, was die Programme aus dem Autostart für ein Arbeitsverzeichnis verwenden, das Du dann auch beim ausführen mit ShellExecute übergeben musst.
Wenn das Verzeichnis immer das aktuelle Verzeichnis ist in dem sich das Programm befindet, dann übergebe einfach nil bei ShellExecute als Arbeitsverzeichnis.

Flare 15. Sep 2006 15:33

Re: Programmstart durch Autostart - kann man das herausfinde
 
Gut, werde ich mal probieren!

(Und ich finde es seltsam, dass sich ICQ und MSN sowie ein paar andere Programme extra wieder beenden obwohl ich möchte, dass die gestartet werden...ich finde das unnötige Programmierarbeit - und für mich mehr :? )


Flare

Martin K 15. Sep 2006 15:46

Re: Programmstart durch Autostart - kann man das herausfinde
 
Also ich hab jetzt selber mal geguckt, als Arbeitsverzeichnis wird wohl der %HomePath% übergeben.
Ist das bei Dir auch so?

Flare 16. Sep 2006 10:23

Re: Programmstart durch Autostart - kann man das herausfinde
 
Bei mir ist das auch so. Also habe ich einfach mal eine Funktion gesucht womit man eben diesen Homepath bekommt und habe zum Glück bei Lucky nach langer Zeit etwas gefunden :roll:

Das dumme nur, für den Homepath scheint keine Konstante festgelegt zu sein, also habe ich durchgetestet und eine Zahl gefunden, die man als Homepath durchgehen lassen kann.

Also habe ich das ganze schnell noch in mein Programm implementiert und siehe da: nix passiert :wall:

Aber wenigstens weiß ich jetzt wie man die Funktion GetShellFolder verwendet :mrgreen:

Hier mal mein relevanter Code, vielleicht habe ich ja auch irgendwo nen Fehler den ich nicht sehe:
Delphi-Quellcode:
procedure TForm3.buttonclick(Sender: TObject);
var button: TButton;
    name,workdir: string;
begin
  if Sender is TButton then
  begin
    name := programs[(Sender as TButton).tag]; //z.B. "C:\Programme\Messenger\msmsgs.exe" /background
    if pos('"', name)>0 then
    begin
      //vielleicht kommt ja noch was hier rein
    end
    else
    begin
      name := '"' + name + '"';
    end;
    workdir := GetShellFolder($0028); //z.B. C:\Dokumente und Einstellungen\Flare
    ShellExecute(Handle, nil, PChar(name), nil, PChar(workdir), 0);
  end;
end;

Flare

ringli 16. Sep 2006 10:59

Re: Programmstart durch Autostart - kann man das herausfinde
 
Versuch es doch mal so:
Delphi-Quellcode:
Shellexecute(Handle, nil, 'C:\Programme\Messenger\msmsgs.exe', '/background', nil, 0);
oder

Delphi-Quellcode:
Shellexecute(Handle, nil, nil, '"C:\Programme\Messenger\msmsgs.exe" /background', nil, 0);
Einfach mal ausprobieren ob es so geht. :-)

Flare 16. Sep 2006 11:21

Re: Programmstart durch Autostart - kann man das herausfinde
 
Erstes klappt, Zweites nicht, wobei ich auch nicht weiß wieso das klappen sollte, da du alles als Parameter übergeben möchtest.

Allerdings klappt es auch nur mit dieser Exe! Wenn ich genau das mit ICQ mache passiert nämlich gar nix.
Und außerdem habe ich dann wieder das Problem mit dem extrahieren des Parameters. Bei dem Messenger ist das ja noch einfach, da gibt es ja nur ein Leerzeichen aber darauf kann man sich ja nicht verlassen.

Flare

vlees91 16. Sep 2006 12:22

Re: Programmstart durch Autostart - kann man das herausfinde
 
Mcötest du einfach nur ICQ/MSN im Hintergrund starten?
Wenn ja:
starte es normal über dein Programm und dann gibts glaube ich eine Messager, die man Programmen schicken kann, sodass sie "verschwinden"^^

himitsu 16. Sep 2006 12:40

Re: Programmstart durch Autostart - kann man das herausfinde
 
Zitat:

Zitat von Flare
Zweites nicht, wobei ich auch nicht weiß wieso das klappen sollte, da du alles als Parameter übergeben möchtest.

Zweites kann auch nicht funktionieren, da Shellexecute als ersten 2 Parameter ausschließlich einen Dateinamen erwartet (verlangt) und diese nunmal insgesamt kein Dateiname. :warn:

Flare 16. Sep 2006 12:44

Re: Programmstart durch Autostart - kann man das herausfinde
 
Nein, das möchte ich nicht. Ich möchte es so starten, wie das Programm durch den Autostart gestartet werden möchte. Mein Programm soll ja einen Autostart simulieren der nur nicht direkt beim starten von Windows ausgeführt wird sondern erst wenn der User es möchte.


Flare

Martin K 16. Sep 2006 12:46

Re: Programmstart durch Autostart - kann man das herausfinde
 
Hi,

ersetze mal:
Delphi-Quellcode:
ShellExecute(Handle, nil, PChar(name), nil, PChar(workdir), 0);
durch:
Delphi-Quellcode:
ShellExecute(Handle, 'open', PChar(name), nil, PChar(workdir), SW_ShowNormal);
das ist der normale ShellExecute-Aufruf:
Delphi-Quellcode:
ShellExecute(Handle, 'open', PChar(Dateiname), PChar(Parameter), PChar(Arbeitsverzeichnis), SW_ShowNormal);

Flare 16. Sep 2006 12:54

Re: Programmstart durch Autostart - kann man das herausfinde
 
Ich würde ja jetzt gerne sagen, dass es geklappt hat, aber durch diese beiden Änderungen hat sich gar nix geändert.
Das war es also auch nicht. :wall:

Vielleicht könnte ja mal jemand das bei sich probieren?

Folgende Programme wollen sich nicht per meinem Programm starten:

MSN 2
MSN 7.5
ICQ Lite 5.1
Quick Time
MSN Plus 3


Flare

Martin K 16. Sep 2006 12:58

Re: Programmstart durch Autostart - kann man das herausfinde
 
Vielleicht lässt Du Dir mal den genauen ShellExecute-Aufruf anzeigen, zB:
Delphi-Quellcode:
ShowMessage(name);
ShowMessage(workdir);
Sag mir doch mal, was jeweils bei den Aufrufen von den Programmen wo es nicht klappt, angezeigt wird.

//Edit:
Was ist eigentlich mit den Parametern?
Die Programme werden doch bestimmt im Autostart mit irgendwelchen Parametern gestartet, die hast Du aber in deinem Code von Beitrag #13 nicht berücksichtigt.
Lass Dir die Parameter dann auch mal per ShowMessage anzeigen.

Flare 16. Sep 2006 13:11

Re: Programmstart durch Autostart - kann man das herausfinde
 
OK.

Was ich jetzt gemacht habe:

Ich habe das Extrahieren des Parameters wieder eingefügt (bei String ohne Anführungsstrichen wird nach dem letzten Leerzeichen abgeschnitten, das danach ist dann der Parameter)
Ich habe mir alle 3 Sachen (Dateiname, Parameter und Workdir) per ShoeMessage anzeigen lassen und siehe da!

MSN 2 klappt schon mal, genau so wie MSn Plus 3!

Aber MSN 7.5 und ICQ wehren sich immer noch und jetzt klappt der Autostart meines Sounkartenmixers nicht mehr :wall:
Bei meinem Soundkartenmixer ist nämlich der spezielle Fall, dass der Pfad dorthin ein Leerzeichen drin hat und sonst kein Parameter angefügt ist.

Also ist es auch nicht genau das was ich suche!

Hier nochmal der aktuelle Code:

Delphi-Quellcode:
procedure TForm3.buttonclick(Sender: TObject);
var button: TButton;
    param,name,workdir: string;
    pos1, pos2: integer;
begin
  if Sender is TButton then
  begin
    name := programs[(Sender as TButton).tag];
    if pos('"', name)>0 then
    begin
      pos1 := pos('"', name);
      pos2 := posex('"', name, 2);
      param := Copy(name, pos2+1, MaxInt);
      name := Copy(name, pos1, pos2);
    end
    else
    begin
      if rpos(' ', name)>0 then
      begin
        param := Copy(name, rpos(' ', name) + 1, MaxInt);
        name := Copy(name, 1, rpos(' ', name) - 1);
      end;
      name := '"' + name + '"';
    end;
    workdir := GetShellFolder($0028);
    ShowMessage(name);
    ShowMessage(param);
    ShowMessage(workdir);
    ShellExecute(Handle, 'open', PChar(name), PChar(param), PChar(workdir), SW_ShowNormal);
  end;
end;

Flare

Martin K 16. Sep 2006 13:30

Re: Programmstart durch Autostart - kann man das herausfinde
 
Was wird denn genau bei ShowMessage angezeigt, wenn es nicht funktioniert?
(also MSN 7.5 und ICQ und Sounkartenmixer)

Flare 16. Sep 2006 13:42

Re: Programmstart durch Autostart - kann man das herausfinde
 
Ich werde noch verrückt -.-
Messenger 7 klappt jetzt (wieso auch immer, ich habe nix geändert)
Aber ICQ und Mixer klappen immer noch nicht.

ICQ:
"C:\Programme\ICQLite\ICQLite.exe"
-trayboot
C:\Dokumente und Einstellungen\Flare

Mixer:
"C:\Programme\NVidia"
Corperation\NvMixer\NvMixerTray.exe
C:\Dokumente und Einstellungen\Flare

Also wenn jetzt immer eins mehr klappt bin ich zu frieden :mrgreen: Auch wenn ich dadurch immer noch nicht weiß warum es mal nicht und dann auf einmal doch klappt :wall: Das Ganze sollte doch schon zuverlässig sein.

Flare

Martin K 16. Sep 2006 14:00

Re: Programmstart durch Autostart - kann man das herausfinde
 
also das der Mixer nicht klappt liegt ja wohl auf der Hand:

das Programm:
C:\Programme\NVidia

und als Parameter:
Corperation\NvMixer\NvMixerTray.exe

hier darfst Du nicht an der Leertaste Programm und Parameter trennen.

Flare 16. Sep 2006 14:04

Re: Programmstart durch Autostart - kann man das herausfinde
 
Das ist mir schon klar, bloß wenn du mir mal meinen Code anguckst weißt du auch warum da getrennt wird :zwinker:
Mein Programm weiß doch nicht, dass das Programm keinen Parameter hinten dran hat und denkt, da es keine Anführungsstriche aber ein Leerzeichen hat, dass dort der Parameter anfängt. (Die Anführungsstriche die du da sehen kannst wurden nach dem Trennen eingefügt)

Deswegen hatte ich ja auch schon mal die Frage reingeworfen wie man am Besten den Parameter extrahieren kann.


Flare

Martin K 16. Sep 2006 14:11

Re: Programmstart durch Autostart - kann man das herausfinde
 
Kennst Du die Funktion Delphi-Referenz durchsuchenFileExists() ?

Vielleicht überprüfst Du, bevor Du Parameter und Dateiname an der Leertaste trennst, ob die Datei vorhanden ist...

Übrigens bei meinem AutostartManager habe ich eine ziemlich komplizierte Funktion, um die Datei zu finden.
Dabei werden auch die Pfade in der Umgebungsvariable Path berücksichtigt.
Vielleicht poste ich mal den Code...

phXql 16. Sep 2006 14:20

Re: Programmstart durch Autostart - kann man das herausfinde
 
Wenn ein Programm per Autostart gestartet wird, dann ist der Parent Task "explorer.exe". Wenn es dein Programm startet, dann ist der Parent logischerweise nicht mehr "explorer.exe". Liegts vielleicht daran?

Flare 16. Sep 2006 14:27

Re: Programmstart durch Autostart - kann man das herausfinde
 
Also ob es am Explorer.exe liegt kann ich schlecht sagen ^^°

Und natürlich kenne ich FileExists.
Aber selbst wenn ich das jetzt einbaue und damit dann den Mixer zum laufen bekomme, dann funzt das ICQ immer noch nicht. Ich kann natürlich an dieser Stelle einfach das automatisierende Element in meinem Programm weglassen und einen Hinweis ausgeben, dass man den Parameter entfernen soll, denn dann klappts ja.

Ich denke mal so werde ich es jetzt mahen und melde mich nochmal wenn es danach immer noch (oder schon wieder) Probleme gibt.


Flare

Martin K 16. Sep 2006 14:46

Re: Programmstart durch Autostart - kann man das herausfinde
 
So hab jetzt deinen Code etwas umgebaut und mit den entsprechenden Teilen aus meinem Code ergänzt:
Delphi-Quellcode:
procedure TForm3.buttonclick(Sender: TObject);

function FindExecute(const Command: String): String;

  function GetWinPath(const Path: String): String;
  begin
    Result := StringReplace(StringReplace(StringReplace(StringReplace(Trim(StringReplace(Path, 'file:///', '', [rfIgnoreCase])), '\', PathDelim, [rfReplaceAll]), '/', PathDelim, [rfReplaceAll]), PathDelim+PathDelim, PathDelim, [rfReplaceAll]), '%20', ' ', [rfReplaceAll]);
  end;

  function ExpandEnvironmentPath(const Path: String): String;
  begin
    SetLength(Result, ExpandEnvironmentStrings(PChar(Path), nil, 0));
    ExpandEnvironmentStrings(PChar(Path), PChar(Result), Length(Result));
    Result := PChar(Result);
  end;

var i, j: Integer; Path, PathExt: TStrings;
begin
  Result := ExpandEnvironmentPath(Command);
  Result := GetWinPath(Result);
  if not FileExists(Result) then
  begin
    if DirectoryExists(Result) then
      Result := IncludeTrailingPathDelimiter(Result)
    else
    begin
      Path := TStringList.Create;
      PathExt := TStringList.Create;
      try
        Path.Delimiter := PathSep;
        Path.DelimitedText := GetEnvironmentVariable('Path');
        Path.Append(GetShellFolder($0028));
        PathExt.Delimiter := PathSep;
        PathExt.DelimitedText := LowerCase(GetEnvironmentVariable('PathExt'));
        if PathExt.Count > 0 then
          for i := 0 to Pred(PathExt.Count) do
            if FileExists(ChangeFileExt(Result, PathExt[i])) then
            begin
              Result := ChangeFileExt(Result, PathExt[i]);
              Exit;
            end;
        if Path.Count > 0 then
          for j := 0 to Pred(Path.Count) do
          begin
            if FileExists(IncludeTrailingPathDelimiter(Path[j])+Result) then
            begin
              Result := IncludeTrailingPathDelimiter(Path[j])+Result;
              Exit;
            end
            else
            if DirectoryExists(IncludeTrailingPathDelimiter(Path[j])+Result) then
            begin
              Result := IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(Path[j])+Result);
              Exit;
            end
            else
            if PathExt.Count > 0 then
              for i := 0 to Pred(PathExt.Count) do
                if FileExists(ChangeFileExt(IncludeTrailingPathDelimiter(Path[j])+Result, PathExt[i])) then
                begin
                  Result := ChangeFileExt(IncludeTrailingPathDelimiter(Path[j])+Result, PathExt[i]);
                  Exit;
                end;
          end;
        Result := '';
      finally
        Path.Free;
        PathExt.Free;
      end;
    end;
  end;
end;

var s,param: string; i: Integer; b: Boolean;
begin
  if Sender is TButton then
  begin
    s := FindExecute(programs[(Sender as TButton).tag]);
    param := '';
    if s = '' then
    begin
      s := programs[(Sender as TButton).tag];
      i := 1;
      b := False;
      while (i <= Length(s)) and ((s[i] <> ' ') or b) do
      begin
        if s[i] = '"' then
          b := not b;
        Inc(i);
      end;
      param := Trim(Copy(s, i+1, Length(s)));
      s := FindExecute(StringReplace(Trim(Copy(s, 1, i-1)), '"', '', [rfReplaceAll]));
    end;
    if s = '' then
      ShowMessage('Fehlerhafter Autostart-Eintrag')
    else
      ShellExecute(Handle, 'open', PChar(s), PChar(param), PChar(GetShellFolder($0028)), 1);
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:06 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