PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : .NET CF: Multiple Instanzen verhindern


Shink
2006-06-13, 16:43:37
Fällt irgendwem eine Lösung im .NET CF (z.B. c#) ein, wie ich verhindern kann, dass unter Windows CE eine Applikation mehr als einmal gestartet wird?

Named Mutex funktioniert bei .NET CF anscheinend nur auf Threadebene (?) und mit einem Absturz sollte der Ansatz auch zustandekommen.

Gast
2006-06-13, 19:50:57
Wie es genau mit dem Compact Framework bei Windows CE aussieht, kann ich dir leider nicht sagen. Aber bei über Win32 machst du das so:


private const int WS_SHOWNORMAL = 1;

[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

private static Process RunningInstance()
{
Process current = Process.GetCurrentProcess();

Process[] processes = Process.GetProcessesByName(current.ProcessName);

foreach(Process process in processes)
{

if(process.Id != current.Id)
{
if(Assembly.GetExecutingAssembly().Location.Replace("/", "\\") = current.MainModule.FileName)
{
return process;
}
}
}

return null;
}


private static void HandleRunningInstance(Process instance)
{

ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL);
SetForegroundWindow(instance.MainWindowHandle);
}

[STAThread]
public static void Main()
{
Process instance = RunningInstance();

if(instance == null)
{

Application.Run(new StartForm());
}
else
{
HandleRunningInstance(instance);
}
}

Shink
2006-06-14, 08:30:30
Process gibt es im .NET CF nicht.

Mein Problem ist übrigens, dass ich eine Hardware-Library verwende, die bei gleichzeitiger Verwendung von 2 Prozessen das Gerät erhängt...

SgtTynis
2006-06-14, 08:37:10
Dann mittels Mutex loesen:

bool newMutexCreated;
Mutex mutex = new Mutex(true, "MyApp", out newMutexCreated);
if (!newMutexCreated) return;
else <Anwendung starten>

Edit: Hmm, wer lesen kann ist klar im Vorteil. Aber warum soll das nicht in CF gehen?

#44
2006-06-14, 09:02:07
Hmmm: Beim VC#2005 kann man multiple Instanzen per Option verbieten... (vlt hilft dir das *irgendwie* weiter)

To create a single-instance application

1. With a project selected in Solution Explorer, on the Project menu, click Properties.
2. Click the Application tab.
3. Select the Make single instance application check box.

Edit: ist in VB2005 so...

Shink
2006-06-14, 09:24:56
@SgtTynis: Hab selber erst grad bemerkt, dass es im .NET CF keinen Konstruktor für named Mutexen gibt, das könnte wohl der Grund sein...

@#44: Ich habe kein VC#2005 (die Express Edition unterstützt - wenn ich mich richtig erinnere - keine Mobile Devices, oder?)

Das schöne daran ist, das der Touchscreen von diesen Geräten so bescheuert ist, dass man Anwendungen manchmal ungewollt doppelt aufmacht.

Übrigens: ich hab Microsoft Windows CE .NET Version 4.20

#44
2006-06-14, 09:29:06
Ich meinte ja nur das du evlt nach einer ähnlichen Option suchen könntest... ;)

HellHorse
2006-06-14, 09:30:42
Lockfile? Port öffnen?

Gast
2006-06-14, 09:54:52
HellHorse[/POST]']Lockfile? Port öffnen?

Funktioniert das auch, wenn du eine Kopie von der auszuführenden Datei erstellst? Ich glaube eher nicht. Außerdem wäre es wünschenswert, wenn beim Doppelklick auf die Datei die aktive Instanz in den Vordergrund gebracht wird.

Shink
2006-06-14, 09:55:21
HellHorse[/POST]']Lockfile? Port öffnen?
Hab ich mir auch schon gedacht.

Lockfile: Irgendwie pervers auf einem Gerät mit Flash-Speicher, aber egal, damit würds eigentlich funktionieren.

Port öffnen: Hab ich irgendwie nicht gebacken bekommen; so wie auf normalem .NET gehts schon einmal nicht: Die Instanzierung des TcpListeners wirft eine Runtime-Exception.

Beide Lösungen haben den Nachteil, dass irgendetwas offen bleiben könnte wenn die Anwendung unerwartet abstürzt.

Gast
2006-06-14, 10:20:06
Also ich mach das immer so:

Process aProcess = Process.GetCurrentProcess();
string aProcName = aProcess.ProcessName;

if (Process.GetProcessesByName(aProcName).Length > 1)
{
MessageBox.Show("Anwendung läuft schon!");
}

Gast
2006-06-14, 10:28:08
Shink[/POST]']Process gibt es im .NET CF nicht.


Ok, dann schau doch mal hier nach:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/ProcessManager.asp

Shink
2006-06-14, 10:58:28
Gast[/POST]']Ok, dann schau doch mal hier nach:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/ProcessManager.asp
OK, da wird geschrieben, wie man mit nativen Libraries von Windows CE selbst eine Process-Klasse bastelt. Das ist zumindest schon einmal etwas. Mal schauen, ob ich mir das antu, noch eine plattformabhängige Library zu verwalten. (Das Programm läuft auch auf PCs, da gibts dann ein Interface zur Abstraktion dieser problematischen HW).

HellHorse
2006-06-14, 12:21:25
Gast[/POST]']Funktioniert das auch, wenn du eine Kopie von der auszuführenden Datei erstellst?
Sicher, solange das Lockfile nicht die auszführende Datei ist.

Gast
2006-06-14, 12:59:15
HellHorse[/POST]']Sicher, solange das Lockfile nicht die auszführende Datei ist.

Ich denke LockFile lockt eine Datei zum Prozess, also eben die ausführende Datei (exe), damit wir nicht mehrere Prozess Instanzen erstellen können. Wenn ich zuvor eine Kopie davon erstelle, in einem ganz anderen Ordner, sind es ja zwei vollkommen unterschiedliche Dateien. D.h. dass beim Start zwar Datei A zum Prozess gelockt werden würde, aber man könnte dann immer noch Datei B starten.

Gast
2006-06-14, 14:04:49
Könnte man nicht einfach beim Programmstart eine versteckte Datei anlegen, die beim Beenden wieder gelöscht wird. Das Programm prüft, ob die Datei existiert und beendet sich bei Vorhandensein. Das würde auch verhindern, dass jemand das Programm umbenennt und so noch einmal starten kann.

Xmas
2006-06-14, 14:40:47
Gast[/POST]']Ich denke LockFile lockt eine Datei zum Prozess, also eben die ausführende Datei (exe), damit wir nicht mehrere Prozess Instanzen erstellen können. Wenn ich zuvor eine Kopie davon erstelle, in einem ganz anderen Ordner, sind es ja zwei vollkommen unterschiedliche Dateien. D.h. dass beim Start zwar Datei A zum Prozess gelockt werden würde, aber man könnte dann immer noch Datei B starten.
Du musst natürlich immer denselben absoluten Pfad zu der Lockdatei verwenden. Wenn ein Prozess diese Datei exklusiv gelockt hat, kann das kein anderer mehr tun, solange dieser Prozess die Sperre nicht freigibt.

Shink
2006-06-14, 15:48:06
Gast[/POST]']Könnte man nicht einfach beim Programmstart eine versteckte Datei anlegen, die beim Beenden wieder gelöscht wird. Das Programm prüft, ob die Datei existiert und beendet sich bei Vorhandensein. Das würde auch verhindern, dass jemand das Programm umbenennt und so noch einmal starten kann.
Nur blöd, wenn das Programm "unnormal" beendet wird und die Datei nicht mehr löschen kann. Nein, ein Lock auf die Datei ist schon notwendig; so hab ichs jetzt ersteinmal auch gelöst (wenn es mir auch nicht wirklich gefällt)

Gast
2006-06-14, 16:04:40
Xmas[/POST]']Du musst natürlich immer denselben absoluten Pfad zu der Lockdatei verwenden. Wenn ein Prozess diese Datei exklusiv gelockt hat, kann das kein anderer mehr tun, solange dieser Prozess die Sperre nicht freigibt.

Eben.

Gast
2006-06-14, 16:08:33
Shink[/POST]']Mal schauen, ob ich mir das antu, noch eine plattformabhängige Library zu verwalten.

Antun? Das ist ja nun wirklich kein rocket sience und in ca. 15min runtergeschrieben.

Shink
2006-06-15, 14:59:33
Gast[/POST]']Antun? Das ist ja nun wirklich kein rocket sience und in ca. 15min runtergeschrieben.
Nun, ich meine tatsächlich die Verwaltung und nicht die Implementierung. Was tu ich z.B. auf Windows XP oder Linux+Mono Systemen? Die HW wird emuliert, wenn nicht vorhanden, doch es wär halt schön wenn ich den plattformunabhängigen Teil so klein wie möglich mache. Aber du hast natürlich recht, das wär schon hinzubekommen.