Programm nur 1x starten

  • Allgemein

Es gibt 28 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Programm nur 1x starten

    Hey Leute,

    Ich möchte ein Programm so konfigurieren, das es sich nur 1x starten lässt. Natürlich könnte ich jetzt bei den Einstellungen ein Haken bei "Einzelanwendung erstellen" setzen. Das Problem dabei ist jedoch, das es dann weder eine Meldung noch sonst was gibt. Daher würde ich das ganze lieber per Code regeln und dazu soll eine Meldung kommen.

    Dazu habe ich auch schon ein Code angefertigt:

    VB.NET-Quellcode

    1. Dim RunningProcesses As Process() = Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName)
    2. If (RunningProcesses.Length > 1) Then
    3. MessageBox.Show("Programm offen")
    4. GC.Collect()
    5. End


    An sich funktioniert das ganze sehr gut, jedoch kann man diesen Code "umgehen" indem man das Programm öffnet, dann die .exe umbenennt. Dann kann man die umbenannte .exe nochmals starten!
    Das ganze liegt ja daran, das geschaut wird, ob der Prozess schon ausgeführt wird. Und wenn man die .exe umbenennt, so startet der Prozess unter einen anderen Namen. Daher wäre es am einfachsten, das Programm so zu konfigurieren, das es immer unter den gleichen Prozess-namen startet, egal wie die .exe heißt. Ist aber sowas überhaupt möglich? Gibt es diesbezüglich auch eine andere Methode?

    Über Hilfe würde ich mich freuen. =)

    Gruß

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Jowat schrieb:

    ein Haken bei "Einzelanwendung erstellen" setzen
    und bei den Anwendungsereignissen ApplicationEvents auswählen:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Leider kenne ich mit Mutex nicht aus =/ und bei ApplicatinEvents soll ich einfach den selben Code nochmal im StartUp schrieben? Das bringt doch nichts, oder?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Das sind nur ein paar Zeilen Code:

    VB.NET-Quellcode

    1. Dim firstInstance As Boolean
    2. Dim m As New Mutex(False, "<Mutex-Name>", firstInstance)
    3. If Not firstInstance Then
    4. m.Close()
    5. m = Nothing
    6. 'hier wird bereits eine Instanz der Anwendung ausgeführt
    7. 'also alles nötige regeln und dann Anwendung schließen
    8. End If
    Als Mutex-namen solltest du etwas wählen, was möglichst eindeutig auf deine Anwendung bezogen ist, da du kein Risiko eingehen willst, das du mit anderen Anwendungen in die Quere kommst.

    Jowat schrieb:

    Das bringt doch nichts, oder?
    Mach da einfach mal eine MessageBox rein und sieh, was passiert.
    Du kannst dann z.B. die Kommandozeile an die andere Instanz durchreichen.
    ----
    Bei der Lösung von @Artentus: mit dem Mutex solltest Du zumindest dafür Sorge tragen, dass die 1. Instanz angezeigt wird, wenn sie minimiert ist und dann den Fokus bekommt.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also,

    @RodFromGermany: Ich meinte mit das es nichts bringt, das es doch genau wie Form-Load Ereignis ist, also das ich den Code stattdessen im Form-Load Ereignis machen könnte.

    Und das mit Mutex kriege ich irgendwie nicht hin. X(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Okay das ganze geht undzwar so:

    VB.NET-Quellcode

    1. Private Sub MyApplication_StartupNextInstance(
    2. ByVal sender As Object,
    3. ByVal e As Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs
    4. ) Handles Me.StartupNextInstance
    5. Dim inputArgument As String = "/input="
    6. Dim inputName As String = ""
    7. For Each s As String In e.CommandLine
    8. If s.ToLower.StartsWith(inputArgument) Then
    9. inputName = s.Remove(0, inputArgument.Length)
    10. End If
    11. Next
    12. If inputName = "" Then
    13. MsgBox("Programm läuft bereits.", MsgBoxStyle.Critical)
    14. End If
    15. End Sub


    Das Problem: Meine Form ist im immer im Vordergrund (Per Code so geregelt) Daher ist die MsgBox hinter der Form. (Die MsgBox erscheint, wenn man das Programm zum 2. mal öffnet). Und man kann wenn die MsgBox da ist, das Programm weder benutzen noch bewegen. Ist das auch noch irgendwie möglich, das zu ändern?

    Gruß

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Jowat schrieb:

    im Form-Load Ereignis machen könnte.
    Wenn Du nur eine Instanz Deiner Form haben möchtest, kannst Du sicher sein, dass das Form_Load-Ereignis auch nur ein Mal aufgerufen wird.
    In Anlehnung an @Artentus: mach Dir einfach eine passende Prozedur, die Du von überall, von wo es erforderlich ist, aufrufen kannst, und da packst Du rein, was hi und da ausgeführt werden muss.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also habe das jetzt mit Mutex gelöst und zwar so:

    VB.NET-Quellcode

    1. Dim firstInstance As Boolean
    2. Dim m As New Mutex(False, "<Mutex-Name>", firstInstance)
    3. If Not firstInstance Then
    4. m.Close()
    5. m = Nothing
    6. MsgBox("Das Programm läuft bereits")
    7. Me.Close()
    8. End If


    Also falls das Programm erneut gestartet wird, so werden die beiden Zeilen mit der MsgBox und Me.Close ausgeführt. Das Problem ist jedoch, das wenn ich das Programm öffne, wenn es schon offen ist, erscheint diese MsgBox und wenn ich dann auf OK klicke, schließt sich nicht das Programm, sondern stürzt ab. Liegt wohl daran, dass das Programm schon im Load Ereignis geschlossen wird oder?

    Gruß

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Jowat schrieb:

    Also habe das jetzt mit Mutex gelöst und zwar
    steht der Code bei mir an dieser und jener Stelle:

    VB.NET-Quellcode

    1. .....
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Also, ich glaube das ich es jetzt verstanden habe. Ich hab da ganze jetzt so gemacht:

    VB.NET-Quellcode

    1. Dim firstInstance As Boolean
    2. Dim m As New Mutex(False, "<Mutex-Name>", firstInstance)
    3. Sub Main()
    4. If Not firstInstance Then
    5. m.Close()
    6. m = Nothing
    7. MsgBox("Das Programm läuft bereits")
    8. Me.Close()
    9. End If
    10. End Sub
    11. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    12. Main()
    13. End Sub



    Nun wenn das Programm das erste mal geöffnet wird passiert nichts. Und wenn es ein zweites mal geöffnet wird dann kommt die Meldung, dass das Programm bereits läuft! Doch dann stürzt es ab, statt sich selbst zu beenden! (Fehlermeldung: "Das Programm läuft nicht mehr" Es wird nach einer Lösung für das Problem gesucht) Und ich könnte den ganzen Code doch auch direkt in das Form_Load Ereignis klatschen, da ich es auch nur im Load Ereignis benutzen will.

    Gruß

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()

    Na, Me.Close kannst du in der Main-Methode nicht verwenden. Da kannst du einfach Return benutzen, um aus der Methode rauszugehen, was folglich auch das Programm beenden wird.
    Der Fehler entsteht bei dir auch nur, weil du "Main" zu einer Instanzmethode gemacht hast. Es muss aber eine statische Methode sein, und du solltest sie auch in ein anderes Modul auslagern. WEiterhin musst du dieses Modul dann als Startobjekt in den Projekteigenschaften festlegen.

    Jowat schrieb:

    Ich hab da ganze jetzt so gemacht:
    Das ist falsch.
    Frag mal Frau Google nach c# single instance (nicht aber vb.net ...).
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hey,

    Also bei mit hat eine einfach Return Anweisung, zumindest unter NF2, nicht funktioniert. Daher habe ich Application.Exit genommen, was problemlos ging. Nun habe ich das ganze direkt im Form_Load Ereignis gemacht. Und das geht auch Problemlos. Und da ich das ganze ja nur um Load Ereignis nutzen will kann es doch auch direkt im Load Ereignis nutzen oder?

    @RodFromGermany: Diesen Code habe ich auch zuerst genutzt, aber das Problem dabei war, das es nicht mehr funktionierte, wenn man die .exe (somit auch den Prozess) umbenannt hat.

    Gruß

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Jowat“ ()