Visual Studio 2008, CF2
Hallo,
ich habe hier viele Ansätze und Lösungen mit System.Threading.Mutex gelesen, die ein mehrfaches Starten der Applikation verhindern.
Leider gibt es diese Möglichkeit unter CF2 nicht.
In der OpenNetCF Klasse gibt es die Applikation2.Run Methode:
public static void Run(
Form mainForm,
bool runAsSingletonApp,
bool displayMainForm
)
Nun habe ich es mit
Applikation2.Run(new MainForm(),true,true)
versucht, aber da bekomme ich auch nicht den gewünschten Erfolg.
Gibt es da vielleicht eine bessere und funktionierende Lösung?
Besten Dank
dimuwe
try
{
//eine leere datei erstellen und diese für die gesamte programmlaufzeit sperren:
GcHandle.Alloc(new Filestream("temp.tmp",openORCreate,Access.Read,Share.None)); // Share.None ist wichtig!
}
catch()
{
//kein lesezugriff möglich -> datei muss von anderer instanz verwendet werden!
}
Hallo Floste,
danke für deine Antwort.
Mit einer Datei habe ich im Moment laufen, was mir aber so unsicher erscheint.
static void Main()
{
//Lets check if another instance of the application is already running.
string AppDirectory = System.IO.Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().GetModules()[0].FullyQualifiedName);
System.IO.FileInfo fiFile = null;
foreach (string s in System.IO.Directory.GetFiles(AppDirectory))
{
fiFile = new System.IO.FileInfo(s);
if (fiFile.Extension == ".proc")
{
try
{
if ((System.Diagnostics.Process.GetProcessById (Convert.ToInt32 (fiFile.Name.Replace (fiFile.Extension, "")))).Responding)
{
//if application already runs in another process kill this one
System.Threading.ThreadPool.QueueUserWorkItem (ShowMessage);
System.Threading.Thread.Sleep(3000);
System.Diagnostics.Process.GetCurrentProcess().Kill();
}//end if
}//end try
catch (ArgumentException e)
{
System.IO.File.Delete(s); //löschen wenn Prozess nicht mehr aktiv
string BlossSo = e.Message;
}//end catch
}//end if
}//end foreach
//Lets create a flagfile with the processID as name. so we define that the application is already running one time.
string FileName = System.IO.Path.Combine (AppDirectory, System.Diagnostics.Process.GetCurrentProcess().Id.ToString() + ".proc");
using (System.IO.File.Create(FileName)) { }//end using
//Now lets start the application
try
{
Application2.Run(new frmMain());
}//end try
catch (Exception e)
{
MessageBox.Show(e.Message);
}//end catch
finally
{
// We delete the flag file after application exits
if (System.IO.File.Exists(FileName))
System.IO.File.Delete(FileName);
}//end finally
}
aus diesem Grund dachte ich, dass es mit dem OpenNet oder einer ganz anderen Lösung geht. Vielleicht kann man ja diese noch verbessern?
Gruß
dimuwe
Mutex ist schon das richtige Stichwort: http://www.pda-dev.de/topic.asp?TOPIC_ID=812&SearchTerms=mutex
Robert Wachtel
Folgende Klasse...
namespace OneOfAnAppHelp
{
class AppExecutionManager : IDisposable
{
private bool _isFirstInstance;
private IntPtr _eventHandle = IntPtr.Zero;
#region Imports
[DllImport("Coredll.dll", SetLastError = true)]
static extern IntPtr CreateEvent(IntPtr alwaysZero, bool manualReset, bool initialState, string name);
[DllImport("Coredll.dll", SetLastError = true)]
static extern int CloseHandle(IntPtr handle);
#endregion
public AppExecutionManager(string appName)
{
_eventHandle = CreateEvent(IntPtr.Zero, true, false, appName + "Event");
_isFirstInstance = Marshal.GetLastWin32Error() == 0;
}
public bool IsFirstInstance
{
get { return _isFirstInstance; }
}
public void Dispose()
{
if (_eventHandle != IntPtr.Zero)
CloseHandle(_eventHandle);
}
}
aufgerufen mit
static void Main()
{
using (AppExecutionManager execMgr = new AppExecutionManager("MeinAppName"))
{
if (execMgr.IsFirstInstance)
{
Application.Run(new MainForm());
}
}
}
funktioniert ganz fanatastisch bei mir
Der Code ist nicht von mir sondern aus dem Beispiel names AppOneCopy_CS
LINK
Hallo soma,
das funktioniert wirklich gut und das ohne so eine lästige Datei.
ein Problem wäre noch, dass es sein kann das sich das gestartete Programm hinter ein anderes Fenster legt. Wie bekomme ich das wieder in den Vordergrund?
Besten Dank
dimuwe