Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria
vivo X300 Pro rappresenta un'evoluzione misurata della serie fotografica del produttore cinese, con un sistema di fotocamere migliorato, chipset Dimensity 9500 di ultima generazione e l'arrivo dell'interfaccia OriginOS 6 anche sui modelli internazionali. La scelta di limitare la batteria a 5.440mAh nel mercato europeo, rispetto ai 6.510mAh disponibili altrove, fa storcere un po' il naso
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2 è la nuova handheld PC gaming con processore AMD Ryzen Z2 Extreme (8 core Zen 5/5c, GPU RDNA 3.5 16 CU) e schermo OLED 8,8" 1920x1200 144Hz. È dotata anche di controller rimovibili TrueStrike con joystick Hall effect e una batteria da 74Wh. Rispetto al dispositivo che l'ha preceduta, migliora ergonomia e prestazioni a basse risoluzioni, ma pesa 920g e costa 1.299€ nella configurazione con 32GB RAM/1TB SSD e Z2 Extreme
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
A re:Invent 2025, AWS mostra un’evoluzione profonda della propria strategia: l’IA diventa una piattaforma di servizi sempre più pronta all’uso, con agenti e modelli preconfigurati che accelerano lo sviluppo, mentre il cloud resta la base imprescindibile per governare dati, complessità e lock-in in uno scenario sempre più orientato all’hybrid cloud
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 15-12-2008, 11:57   #1
mcaisco
Member
 
Iscritto dal: Jun 2006
Messaggi: 117
[c#/c++] Eseguire un'applicazione esterna dentro una form

Salve,

una premessa: non sto chiedendo come si esegue un programma esterno. Questo lo so già fare. Ho già guardato un sacco di post qui sul forum e tutti putroppo si riferiscono alla semplice esecuzione di programmi esterni.

Dunque io ho la necessità di eseguire un'applicazione esterna all'interno di una mia form, per la precisione dentro un suo pannello. In altre parole vorrei emulare una sorta di applicazione MDI in cui però le finestre child della principale (la mia applicazione) non sono form da me create, ma applicazioni esterne eterogenee, sul cui codice non ho alcun controllo quindi! Ho guardato un sacco di forum sul web e la cosa è fattibile, ma putroppo tutti gli esempi funzionanti eseguono applicazioni di windows come notepad o la calcolatrice. Queste applicazioni funzionano anche a me nella maniera voluta e questo fa ben sperare. Putroppo però non sempre le cose funzionano. Ad esempio con eseguibili come iexplore.exe (Internet Explorer) o write.exe (Wordpad) succede che l'applicazione esterna viene lanciata ma non viene "inglobata" nella mia form.

Tecnicamente quello che sul web indicano di fare è di usare alcune funzioni win-api dichiarandole esterne dentro il proprio codice "managed" in C# o C++ (o VB.NET).

Ecco un esempio del mio codice FUNZIONANTE (notate che eseguo appunto notepad.exe)
Codice:
// dichiarazione delle funzioni esterne win-api
public:
[DllImport("USER32.DLL")]
static int SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
static bool MoveWindow(IntPtr hwnd, int x, int y, int cx, int cy, bool repaint);

// setting del processo da lanciare
System::Diagnostics::ProcessStartInfo^ psi = gcnew System::Diagnostics::ProcessStartInfo();
psi->WindowStyle = System::Diagnostics::ProcessWindowStyle::Normal;
psi->FileName = "notepad.exe";
psi->Arguments = "";
psi->UseShellExecute = false;
System::Diagnostics::Process^ proc = System::Diagnostics::Process::Start(psi);

// il thread della mia applicazione attende INDEFINITAMENTE fino a quando l'applicazione
// esterna è stata inizializzata correttamente
bool wait = proc->WaitForInputIdle();

// imposto l'handle della finestra della nuova applicazione lanciata come child di
// un pannello della mia form
IntPtr gpsHandle = proc->MainWindowHandle;
SetParent(gpsHandle, panel3->Handle);
MoveWindow(gpsHandle, 0, 0, panel3->Width, panel3->Height, true);
this->panel3->ResumeLayout();
this->panel3->PerformLayout();
this->ResumeLayout();
this->PerformLayout();
Il codice sopra funziona correttamente. Viene lanciato il notepad e la finestra viene inglobata nel pannello della mia form. Ma se si prova a cambiare eseguibile le cose non sempre funzionano. E' come se la funzione WaitForInputIdle() non riesca sempre ad attendere il tempo necessario affinchè la nuova finestra venga inglobata. Con notepad.exe funziona. Con iexplore.exe ad esempio no. Con le applicazioni che devo utilizzare non funziona e queste semplicemente vengono eseguite ma non inglobate. Nei casi in cui le cose funzionano il valore assegnato a gpsHandle è un valore numerico positivo (suppongo un puntatore interno). Nei casi in cui non funziona, gpsHandle è 0 (ma pensa un po'...). Ho indagato anche sul ritorno di WaitForInputIdle e questa procedura ritorna true se la nuova finestra è pronta, false altrimenti. Ma nel mio caso l'attesa dovrebbe essere indefinita e quindi dle tutto bloccante. Invece la procedura ritorna sempre true, anche se poi la finestra non viene inglobata nella mi form.

Ma ecco un trucco strano. Basta sostituire la chiamata alla WaitForInputIdle() con una stupida sleep e tutto funziona. Il problema però è che io non posso sapere a priori quanto sia necessario attendere per una generica applicazione esterna da eseguire. Ho fatto delle prove e con una sleep di 300ms per ora funzionano tutte le applicazioni che ho provato. Con 100ms solo alcune... insomma è un casino!

In definitiva sembra quasi che il processo con la nuova applicazione esterna venga lanciato. Poi però il chiamante (la mia form) non rimane bloccato sulla WaitForInputIdle per un lasso di tempo sufficiente affinché l'handle della finestra associata all'applicazione esterna sia stato correttamente inizializzato. Questo sembra essere erroneo però, perchè la WaitForInputIdle, in mancanza di parametri espliciti, attende il processo chiamato per un tempo indefinito. Invece nel mio caso ritorna sempre immediatamente con valore true, come se avesse rilevato che la finestra dell'applicazione esterna sia stata inizializzata correttamente... anche se poi l'handle rimane a 0! Ovviamente ho anche provato a chiamare WaitForInputIdle passando come parametro il tempo di attesa, ma anche con valori molto alti la funzione ritorna immediatamente, fregandosene altamente insomma!

Potete aiutarmi? Qualcuno sa perchè questa procedura non fa il suo lavoro in alcune circostanze? Perchè con la sleep() le cose funzionano?

Grazie
mcaisco è offline   Rispondi citando il messaggio o parte di esso
Old 15-12-2008, 18:40   #2
mcaisco
Member
 
Iscritto dal: Jun 2006
Messaggi: 117
Nessuno sa aiutarmi? Nessuno ha mai provato ad inglobare una finestra di un programma esterno in una propria form?
mcaisco è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 00:49   #3
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da mcaisco Guarda i messaggi
Nessuno sa aiutarmi? Nessuno ha mai provato ad inglobare una finestra di un programma esterno in una propria form?
Io Internet Explorer l'avevo usato piu' volte in un mio applicativo, cosi' come anche i vari Office.
Ma in maniera ortodossa, usando gli oggetti COM e i controlli relativi.

Per il tuo problema prova a passare delle API, ovvero da OpenProcess. Ti basta sapere il PID e l'handle dovresti prenderlo.
Proseguo. Poi dato il pid passi ad EnumWindows(), La tua e' una delle finestre... qual e' la principale?
Proverei a passare ogni finestra della enumwindows a GetWindowThreadProcessId(), e quando trovo il pid che coincide con quello di lancio, allora dovresti essere davanti alla main.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.

Ultima modifica di gugoXX : 16-12-2008 alle 01:18.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 09:22   #4
mcaisco
Member
 
Iscritto dal: Jun 2006
Messaggi: 117
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Io Internet Explorer l'avevo usato piu' volte in un mio applicativo, cosi' come anche i vari Office.
Ma in maniera ortodossa, usando gli oggetti COM e i controlli relativi.
Sinceramente non conosco gli oggetti COM per controllare applicazioni esterne. Puoi farmi qualche esempio o indicarmi qualche risorsa sul web? Comunque ti chiedo: questi oggetti COM possono essere utilizzati anche per la gestione di applicazioni grafiche esterne generiche o solo applicazioni windows predefinite (come quelle di Office)?

Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Per il tuo problema prova a passare delle API, ovvero da OpenProcess. Ti basta sapere il PID e l'handle dovresti prenderlo.
Proseguo. Poi dato il pid passi ad EnumWindows(), La tua e' una delle finestre... qual e' la principale?
Proverei a passare ogni finestra della enumwindows a GetWindowThreadProcessId(), e quando trovo il pid che coincide con quello di lancio, allora dovresti essere davanti alla main.
Mmm questa cose della EnumWindows() l'ho già vista da qualche parte mi pare. Effettivamente non ho provato. Comunque il mio dubbio è che la form principale, senza una sleep() o questa fantomatica WaitForInputIdle() fra la chiamata alla OpenProcess() e l'accesso al PID del processo o all'handle della finestra, non sempre dà il tempo all'applicazione esterna di essere effettivamente inizializzata, perchè comunque la OpenProcess() non è una chiamata bloccante. Comunque proverò anche questa via.

Grazie mille
mcaisco è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 10:15   #5
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Secondo me dovresti seguire i consigli di GugoXX.
Io posto solo per "toglierti il prurito" riguardo la faccenda della WaitForInputIdle che torna subito.

E' bastata una ricerca di 5min. con Google per trovare questo:
LINK
estratto:
Quote:
...
Well, this is weird. I searched for doc on the internet and that description
differs:
The process you're waiting for needs to have a message queue (it does in my
case), not the process that calls WaitForInputIdle.
Hans

---
---
Waits until the specified process is waiting for user input with no input
pending, or until the time-out interval has elapsed.

DWORD WINAPI WaitForInputIdle(
HANDLE hProcess,
DWORD dwMilliseconds
);
Parameters
hProcess
[in] A handle to the process. If this process is a console application or
does not have a message queue, WaitForInputIdle returns immediately.
dwMilliseconds
[in] The time-out interval, in milliseconds. If dwMilliseconds is
INFINITE, the function does not return until the process is idle.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 11:30   #6
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
Quote:
Originariamente inviato da mcaisco Guarda i messaggi
...
Basta sostituire la chiamata alla WaitForInputIdle() con una stupida sleep e tutto funziona. Il problema però è che io non posso sapere a priori quanto sia necessario attendere per una generica applicazione esterna da eseguire. Ho fatto delle prove e con una sleep di 300ms per ora funzionano tutte le applicazioni che ho provato. Con 100ms solo alcune... insomma è un casino!
...
Potete aiutarmi? Qualcuno sa perchè questa procedura non fa il suo lavoro in alcune circostanze? Perchè con la sleep() le cose funzionano?
Secondo me la risolvi con la Sleep, usata in modo un po' più "furbo", e chiamando in causa anche un controllo periodico sul MainWindowHandle.
Ho fatto una prova veloce ( VB 2008 ) e sono riuscito ad aprire nella mia Form ( che non è manco MDI, come invece consigliato da molti suggerimenti online ) tutti gli applicativi Office, notepad, wordpad, Internet Explorer, ecc...

In soldoni :

Codice:
Public Class Form1

    Private Declare Auto Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim PSI As New ProcessStartInfo("iexplore.exe")
        Dim P As Process = Process.Start(PSI)
        Dim i As Integer = 0
        For i = 0 To 1000
            System.Threading.Thread.Sleep(10)
            P.Refresh()
            If P.MainWindowHandle <> IntPtr.Zero Then Exit For
        Next i
        SetParent(P.MainWindowHandle, Me.Handle)

    End Sub

 End Class
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 11:56   #7
MarcoGG
Senior Member
 
L'Avatar di MarcoGG
 
Iscritto dal: Dec 2004
Messaggi: 3210
... E tradotto in C# :

Codice:
   public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);

        private void button1_Click(object sender, EventArgs e)
        {
            ProcessStartInfo PSI = new ProcessStartInfo("iexplore.exe");
            Process P = Process.Start (PSI);
            for(int i = 0;i<1000;i++)
            {
                System.Threading.Thread.Sleep(10);
                P.Refresh();
                if(P.MainWindowHandle != IntPtr.Zero)
                {
                    break;
                }
            }
            SetParent(P.MainWindowHandle, this.Handle);
        }
    }
MarcoGG è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 12:24   #8
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da MarcoGG Guarda i messaggi
... snip ...
Volpone!
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 12:29   #9
mcaisco
Member
 
Iscritto dal: Jun 2006
Messaggi: 117
Quote:
Originariamente inviato da banryu79 Guarda i messaggi
Secondo me dovresti seguire i consigli di GugoXX.
Io posto solo per "toglierti il prurito" riguardo la faccenda della WaitForInputIdle che torna subito.

E' bastata una ricerca di 5min. con Google per trovare questo:
LINK
Mmm, avevo già letto questa pagina ed in effetti non è che chiarisca molto, anzi alla fine aggiunge dubbi sul vero funzionamento di questa procedura. Però ho riflettuto di nuovo e le cose in effetti mi sembrano strane.

Allora...
Quote:
The process you're waiting for needs to have a message queue (it does in my
case), not the process that calls WaitForInputIdle.
Il mio caso è identico, nel senso che avvio applicazioni grafiche che quindi hanno un message queue (altrimenti ritorna un preciso errore su questo fatto!). Mi fa pensare invece quel "not". Leggendo così sembra che il significato sia questo: il processo su cui sto attendendo deve avere un message queue, e non quello che chiama la WaitForInputIdle(). Ma a me pare che io nel codice faccia proprio questo con:

ProcessStartInfo PSI = new ProcessStartInfo("myApp.exe");
Process P = Process.Start (PSI);
P->WaitForInputIdle()

No?!

Quote:
Waits until the specified process is waiting for user input with no input
pending, or until the time-out interval has elapsed.
...
hProcess
[in] A handle to the process. If this process is a console application or
does not have a message queue, WaitForInputIdle returns immediately.
...
Questo mi conferma le cose, anche se qui parla della procedura omonima winapi (ma alla fine la procedura che chiamo, all'interno usa proprio quella). Quel "Waits" iniziale si riferisce alla form principale no?! Quindi teoricamente il processo "padre" attende fino a quando il processo "figlio" (che chiama la WaitForInputIdle()) non termina la sua attesa.

Perchè quindi se chiamo sta benedetta WaitForInputIdle() sul nuovo processo creato per l'applicazione esterna, il chiamante, cioè la form principale, non sta lì fermo e buono ad aspettare?
mcaisco è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 13:10   #10
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Ogni processo potrebbe avere piu' di una finestra.
Il problema e' che per qualche applicazione il processo principale (spesso l'unico) coincide con una finestra, che coincide anche con la finestra principale (Notepad).
Per altre applicazione il processo principale, anche se unico, non coincide con la finestra principale. Per I.E. ho idea che il processo principale si tratti di un Loader, che si occupa di istanziare e lanciare i thread delle finestre, una delle quali sara' la principale per l'applicazione, ma verra' istanziata, aperta e sara' pronta solo in un secondo tempo.

La WaitForInputIdle, cosi' come la MainWindowHandle del C# fanno parecchie cose sotto la coperta, richiamando parecchie API, in un modo simile a quello che ho provato ad esporre sopra.

Sta di fatto che quando richiarmi WaitForInputIdle il processo principale non ha ancora avuto tempo di creare le finestre (almeno la principale), e quindi non si tratta ancora di un processo con una finestra principale. Per questo motivo ricade ancora nei "processi senza finestra", e ritorna subito.
D'altronde il C# non puo' sapere che prima o poi quel processo avra' una finestra principale (non lo sa nemmeno quel processo stesso...) e quindi non stara' ad aspettare senza sapere se mai dovra' ritornare.

Se invece aspetti un po' di tempo, il processo avra' avuto modo di creare tutto il necessario, e C# si trovera' aggiornate variabili come MainWindowHandle (che appunto sotto la coperta fa parecchie cose).
E anche WaitForInputHandle funzionera' come atteso, dato che i 2 campi sono fra loro in relazione.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 14:10   #11
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
... snip ...
Grande GugoXX, grazie della spiegazione!
Ragazzi, siete dei pozzi di scienza infusa
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 15:23   #12
mcaisco
Member
 
Iscritto dal: Jun 2006
Messaggi: 117
Grazie mille GugoXX della spiegazione. Quindi a questo punto non c'è modo di essere sicuri che un'applicazione abbia creato la finestra principale. Dunque sembra che l'unico approccio certo è l'utilizzo di una sleep() prima della lettura dell'handle MainWindowHandle, magari ottimizzato come ha suggerito MarcoGG.
Concordate?

Ah però in effetti c'era anche il metodo sempre di GugoXX che suggeriva di rintracciare il processo lanciato con il suo PID e la EnumWindows()... però se non vado errato, anche in questo caso dovrei comunque attendere un po' prima di provare a rintracciare il processo, in modo da dargli tempo di costruire la finestra principale. Giusto?
mcaisco è offline   Rispondi citando il messaggio o parte di esso
Old 16-12-2008, 15:33   #13
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da mcaisco Guarda i messaggi
Grazie mille GugoXX della spiegazione. Quindi a questo punto non c'è modo di essere sicuri che un'applicazione abbia creato la finestra principale. Dunque sembra che l'unico approccio certo è l'utilizzo di una sleep() prima della lettura dell'handle MainWindowHandle, magari ottimizzato come ha suggerito MarcoGG.
Concordate?
Il polling proposto da MarcoGG mi sembra una buona soluzione per il tuo problema.

Prova ancora a verificare che per le applicazioni che vorresti usare non esista un componente COM gia' pronto.
Se stai usando C#, prova ad aggiungere un riferimento di tipo COM alla tua applicazione. Dovresti vedere un lungo, lunghissimo elenco di tutti componenti COM disponibili sulla tua macchina.
Se le applicazioni di tuo interesse espongono un controllo COM dovresti vederlo li', e dovresti poterlo aggiungere al tuo progetto. A quel punto ti ritroveresti con il controllo disponibile sulla toolbar, pronto per essere usato sulla tua Form come un qualsiasi altro controllo (quasi, un po' piu' rognoso).

Questo e' il modo migliore.
Certo, se non hanno pensato di fare un controllo COM non puoi percorrere questa strada.
Come dicevo appunto InternetExplorer e' un Controllo Com utilizzato poi da una finestra (se non sbaglio il controllo di InternetExplorer si chiama axBrowser qualcosa)
E cosi' anche i vari applicativi Office.
Ma anche altri, es: VLC.

In C#, per lo stesso motivo, quando si progettano applicazioni con parti GUI, e' bene separare la parte grafica dalla parte logica, mettendo la parte grafica dentro un controllo in un progetto di tipo WindowsFormControlLibrary, la parte logica in un altro progetto di tipo Library a se stante (addirittura di tipo Windows Workflow se si vuole).
In questo modo sara' possibile utilizzare la WindowsFormControlLibrary allo stesso modo che i vecchi COM, dentro nuove applicazioni.
Il progetto principale risulterebbe essere solo un collante, la glue logic che mette insieme i vari pezzi.
Pezzi che possono essere addirittura cambiati in seguito con nuove versioni (retrocompatibili).
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione vivo X300 Pro: è ancora lui il re della fotografia mobile, peccato per la batteria Recensione vivo X300 Pro: è ancora lui il...
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'...
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti AWS re:Invent 2025: inizia l'era dell'AI-as-a-Se...
Cos'è la bolla dell'IA e perché se ne parla Cos'è la bolla dell'IA e perché se...
BOOX Palma 2 Pro in prova: l'e-reader diventa a colori, e davvero tascabile BOOX Palma 2 Pro in prova: l'e-reader diventa a ...
La capsula SpaceX Dragon CRS-33 ha acces...
La NASA è sempre più vicin...
Crisi delle memorie: ASUS torna al passa...
Le console next-generation potrebbero es...
Gemini cresce ancora: la quota di mercat...
Samsung sfida TSMC: la capacità produtti...
Iliad alza il prezzo della fibra ottica ...
Il prossimo low cost di POCO sarà il più...
The Elder Scrolls VI: ecco le ultime sul...
Ecco i saldi di fine anno Amazon, 34 off...
iPhone Fold: scorte limitate al lancio m...
OpenAI porterà la pubblicità in ChatGPT ...
TSMC aumenterà ancora i prezzi: nel 2026...
Marvel pubblica anche il secondo teaser ...
Nuovo accordo tra xAI e il Pentagono: l'...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:20.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v