Torna al Thread
[DllImport("coredll")]
static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, int flAllocationType, int flProtect);
const int MEM_COMMITT = 0x1000;
const int MEM_RESERVE = 0x2000;
const int PAGE_READWRITE = 0x04;
[DllImport("coredll")]
static extern bool VirtualFree(IntPtr lpAddress, int dwSize, int dwFreeType);
const int MEM_RELEASE = 0x8000;
[DllImport("coredll")]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
IntPtr lpBuffer, int nSize, out int plNumberOfBytesRead);
[DllImport("coredll")]
static extern IntPtr OpenProcess(int fdwAccess, bool fInherit, int IDProcess);
[DllImport("coredll")]
static extern bool CloseHandle(IntPtr hObject);
IntPtr memPtr = IntPtr.Zero;
private void TuaForm_Load(object sender, EventArgs e)
{
unsafe
{
string tmpPath = Path.Combine(Path.GetTempPath(), "AliveTest.tmp");
//Verifica l'esistenza del file
if (File.Exists(tmpPath))
{
//Apre il file per leggere il percorso in memoria
FileStream fStr = new FileStream(tmpPath, FileMode.Open, FileAccess.Read);
//Legge i quattro byte che indicano l'id del processo
byte[] idBytes = new byte[4];
fStr.Read(idBytes, 0, 4);
//Legge i 4 byte che identificano l'indirizzo in memoria
byte[] ptrBytes = new byte[4];
fStr.Read(ptrBytes, 0, 4);
//Chiude il file
fStr.Close();
//Lo stato
int status;
try
{
//Ottiene l'indirizzo in memoria
memPtr = new IntPtr(BitConverter.ToInt32(ptrBytes, 0));
//Ottiene il processo dall'id
IntPtr hProc = OpenProcess(0, false, BitConverter.ToInt32(idBytes, 0));
//Legge la memoria dal processo
int data, read;
if (hProc == IntPtr.Zero ||
!ReadProcessMemory(hProc, memPtr, new IntPtr(&status), 4, out read))
{
//Se si sono verificati errori generea un'eccezione
CloseHandle(hProc);
throw new Exception();
}
CloseHandle(hProc);
}
//Se si verificano errori di lettura della memoria
//significa che il processo è terminato e il file
//non è stato eliminato, quindi alloca la nuova memoria
//e scrive l'indirizzo nel file
catch (Exception ex)
{
//Indica che lo stato dovrebbe essere "non avviato"
status = 0;
}
//Se lo stato indica che un'applicazione è in corso
if (status == 1)
{
//Termina il processo corrente
Process.GetCurrentProcess().Kill();
}
//Se invece lo stato non è "applicazione in corso"
//alloca la nuova memoria e scrive l'indirizzo nel file
else
{
//Alloca la memoria
memPtr = VirtualAlloc(IntPtr.Zero, 4, MEM_COMMITT | MEM_RESERVE, PAGE_READWRITE);
//Scrive nella memoria che l'applicazione è in corso
Marshal.WriteInt32(memPtr, 1);
//Scrive l'id del processo nel file
fStr = new FileStream(tmpPath, FileMode.Open, FileAccess.Write);
fStr.Write(BitConverter.GetBytes(Process.GetCurrentProcess().Id), 0, 4);
//Scrive il puntatore nel file
fStr.Write(BitConverter.GetBytes(memPtr.ToInt32()), 0, 4);
fStr.Close();
//Esce dalla funzione
return;
}
}
//Se invece il file non esiste significa che
//nessun'altra istanza dell'applicazione è avviata
else
{
//Quindi alloca la memoria, scrive lo stato e scrive
//l'indirizzo dell'applicazione nel file
FileStream fStr = new FileStream(tmpPath, FileMode.CreateNew, FileAccess.Write);
int* i = (int*)memPtr.ToPointer();
//Alloca la memoria
memPtr = VirtualAlloc(IntPtr.Zero, 4, MEM_COMMITT | MEM_RESERVE, PAGE_READWRITE);
//Scrive nella memoria che l'applicazione è in corso
Marshal.WriteInt32(memPtr, 1);
//Scrive l'id del processo nel file
fStr.Write(BitConverter.GetBytes(Process.GetCurrentProcess().Id), 0, 4);
//Scrive il puntatore nel file
fStr.Write(BitConverter.GetBytes(memPtr.ToInt32()), 0, 4);
fStr.Close();
//Esce dalla funzione
return;
}
}
}
private void Form1_Closed(object sender, EventArgs e)
{
//Alla chiusura del Form elimina il file temporaneo
string tmpPath = Path.Combine(Path.GetTempPath(), "AliveTest.tmp");
if (File.Exists(tmpPath))
File.Delete(tmpPath);
//E dealloca la memoria condivisa
VirtualFree(memPtr, 0, MEM_RELEASE);
}