giovedì, 28 Novembre 2024

[c#] Creare una classe per stampare con i font installati nella stampante

L’obiettivo è quello di inviare del testo alla stampante utilizzando i font nativi al suo interno e la libreria gdi32.dll di Windows. Questa volta integreremo tutto in una semplice applicazione in C#.

Anzitutto creiamo un semplice form con una TextBox chiamata txtTesto ed un Button chiamato btnStampa.

Aggiungiamo poi una nuova classe che estenda la classe System.Drawing.Printing.PrintDocument

Per usare la classe anzitutto dobbiamo implementare alcuni metodi e creare i corrispondenti per le funzioni della libreria GDI32.

A tale scopo utilizzeremo l’istruzione [DllImport("gdi32.dll")] prima delle specifiche definizioni.

Le funzioni che dobbiamo implementare sono rispettivamente: CreateFont, SelectObject, DrawText, DeleteObject

Per maggiori riferimenti alle singole funzioni consiglio di visionare il sito Pinvoke.net

Detto tutto questo costruiamo la classe nel modo seguente:

Eseguiamo il test della funzione nel form principale:

In questo modo stamperemo attraverso la stampante predefinita.

Nel mio caso una stampante Samsung M2070, che riconosce come font “Courier New“.

[python] Utilizzare Python su Apache (configurazione con XAMPP)

Anzitutto assicuriamoci di avere Python installato sul nostro computer. Nel mio esempio procederò con l’installazione su Windows, ma anche nel caso di un server Linux la procedura è pressoché la medesima.

1. Individuiamo la cartella di installazione di Python

Nel mio caso l’eseguibile di Python si trova in D:/Python27/python.exe

Appuntiamoci questo valore perché ci servirà per dopo.

2. Configuriamo Apache modificando il file httpd.conf

Utilizzando XAMPP è sufficiente aprire il pannello di controllo e recarsi su Apache > Config > Apache (httpd.conf)

3. Aggiungiamo il handler per gli script cgi

In fondo al file di configurazione aggiungiamo le seguenti due righe per attivare la gestione degli script cgi

In questo modo permettiamo ad apache di interpretare i file con estensione .py come script eseguibili mediante applicazioni interne al computer.

4. Aggiungiamo index.py alle pagine di default

Esattamente per quello che succede per index.htm oppure index.php, vogliamo che anche index.py venga letta come pagina predefinita di una cartella. (potremmo metterne anche altre a piacere)

Per farlo modifichiamo sempre il file httpd.conf che abbiamo aperto prima. Identifichiamo il punto dove c’è scritto <IfModule dir_module> e modifichiamo la configurazione nel modo seguente, aggiungendo index.py all’elenco

5. Riavviamo apache

Che lo si stia facendo su XAMPP, oppure su un server LAMP, a questo punto riavviamo Apache, banalmente premendo Stop e Start in sequenza.

6. Creiamo la prima pagina in Python

Dentro la cartella htdocs creiamo una cartella a piacere, che allo scopo di questo esempio io chiamerò python.

Dentro la cartella creiamo un file chiamato index.py con dentro le seguenti istruzioni:

Ricordiamoci l’indirizzo preso all’inizio al punto 1. Il percorso di installazione di Python andrà incluso in ciascun file. Inoltre è essenziale il primo print, che permette al browser di interpretare il contenuto come una pagina html.

Le prime 2 righe dovranno essere presenti in ogni pagina che si occuperà dell’output.

7. Esempio di una pagina semplice

Ovviamente dovremo aggiungere tutti gli opportuni tag del HTML, cosa che potremmo fare in questo modo:

8. Raccogliere i dati da POST e GET

Infine vediamo come raccogliere i dati dai due metodi principali con i quali l’utente può interagire con la nostra pagina web, il get e il post.

Per farlo importiamo anzitutto la libreria CGI aggiungendo in cima al file, dopo il percorso all’eseguibile di Python, import cgi

Avremo bisogno anche di gestire eventuali errori che se no non verranno mostrati nell’output. Per farlo importiamo anche cgitb aggiungendo le seguenti due righe:

L’intestazione del nostra file diventerà:

A questo punto per raccogliere i dati, sia da POST che da GET utilizziamo l’istruzione dati = cgi.FieldStorage()

Modifichiamo tutta la pagina per funzionare con un piccolo form che utilizzi entrambi i metodi:

Faccio notare che se si cerca di chiamare la pagina http://127.0.0.1/python/?dati_form=1 si incorrerà in un errore come il seguente (senza la suddetta libreria avremmo visualizzato una pagina bianca):

Questo perché la chiave valore non è definita all’interno del contenitore dati.

Aggiungiamo quindi un controllo nel modo seguente:

 

[bash] Script per reimpostare i permessi della cartella system su Plesk

Oggi mi sono trovato di fronte al problema di reimpostare tutti i permessi sulla cartella /var/www/vhosts/system/ appartenente a Plesk.

Nel caso specifico esiste un articolo di riferimento della guida di Plesk su come reimpostare i permessi e quali dovrebbero essere quelli corretti. Per l’articolo originale vedere: How to restore default permissions in the virtual host directory on Linux?

Nell’articolo è possibile trovare anche un file bash che però non reimposta i permessi sulla cartella system.

Allora ne ho realizzato uno mio, seguendo lo schema dei permessi illustrato nell’articolo medesimo:

Il codice in bash è il seguente:

 

[wordpress] Problema video Revolution Slider 6 con Uncaught TypeError: Cannot read property ‘x’ of undefined

Problema: inserendo in Revolution Slider 6 delle slide con video in HTML5 (file mp4 nel caso particolare) lo slider non riesce ad avviarsi e provoca un loop infinito di errori nella console javascript.

Soluzione: l’errore dipende probabilmente da un altro plugin che provoca incompatibilità nel codice. Nel mio caso specifico l’errore era provocato da Enlighter – Customizable Syntax Highlighter. Disattivando il plugin lo slider torna a funzionare.

Nel caso specifico l’errore che si presenta è il seguente.

Uncaught TypeError: Cannot read property 'x' of undefined
at HTMLVideoElement.computePosition (mootools-core-yc.js?ver=3.10.0:4)
at HTMLVideoElement.setPosition (mootools-core-yc.js?ver=3.10.0:4)
at Object.R (revolution.tools.min.js?ver=6.0:46)
at Object.i._initProps (revolution.tools.min.js?ver=6.0:46)
at Object.i._init (revolution.tools.min.js?ver=6.0:46)
at Object.i.render (revolution.tools.min.js?ver=6.0:46)
at Object.i.render (revolution.tools.min.js?ver=6.0:46)
at Object.E._updateRoot.H.render (revolution.tools.min.js?ver=6.0:46)
at Object.i.dispatchEvent (revolution.tools.min.js?ver=6.0:45)
at s (revolution.tools.min.js?ver=6.0:45)

Oltre a cercare di correggere il file revolution.tools.min.js, cosa che sconsiglio caldamente, conviene verificare quali altri plugin stiano utilizzando mootools, perché probabilmente ci sono delle incompatibilità.

Disattivando il plugin in questione lo slider torna a funzionare correttamente.

[php] Modificare programmaticamente i prezzi nel carrello di WooCommerce su WordPress

Immaginiamo di voler modificare i prezzi dei prodotti su WooCommerce una volta che sono stati inseriti nel carrello. Nel mio esempio voglio aggiungere uno sconto del 50% su un prodotto quando vengono comprati almeno 2 prodotti dello stesso tipo.

Per fare questo anzitutto voglio calcolare quanto verrebbe il costo di un singolo prodotto affinché la somma di tutti i prodotti, dello stesso tipo, risulti tale che 1 solo dei prodotti sia scontato al 50%.

Ammettiamo che n sia il numero di prodotti (n ≥ 2), s lo sconto (nel mio caso 50%) e x il prezzo di ciascun prodotto. Avremo

n*x=x*s+(n-1)*x

x = x*(s+n-1)/n

Stabilito questo usiamo il hook per WooCommerce woocommerce_before_calculate_totals inserendo il nostro calcolo per ultimo (dopo tutti gli eventuali plugin).

La base del codice che vogliamo usare è la seguente:

Questa funzione può essere inserita dentro functions.php del nostro tema.

Detto questo dobbiamo anche prendere in considerazione che sul prezzo finale del prodotto potrebbero incidere ulteriori parametri (derivati magari da altri plugin) che potrebbero variare il prezzo. Per ovviare a questo problema legherò il hook alla fine di tutte le altre eventuali operazioni (da qui il valore 1000 nell’ordinamento di esecuzione del hook) e calcolerò il prezzo a partire da quello base, applicando poi il modificatore che sarebbe risultato prima del mio sconto.

La nuova funzione sarà la seguente:

Volendo calcolare il valore scontato al 50% al parametro p ho inserito il valore 0.5.

In questo modo calcoliamo il prezzo finale che dovrebbe avere ciascun prodotto, affinché risulti che la somma dei prodotti sia la somma di un prodotto scontato al 50% e di tutti gli altri a prezzo pieno (compresi gli eventuali modificatori).

[android] Macchina virtuale AVD estremamente lenta a partire e nell’esecuzione

Problema: la macchina virtuale AVD (Android Virtual Device) è estremamente lenta sia nell’avvio che durante l’esecuzione

Soluzione: Installare Intel x86 Emulator Accelerator (HAXM) dall’SDK Manager e utilizzare l’opzione Host GPU.

Apriamo anzitutto l’SDK Manager e dalla sezione Extras assicuriamoci che sia installato il pacchetto Intel x86 Emulator Accelerator (HAXM installer). Se non lo fosse installiamolo.

Quando poi configuriamo la macchina virtuale assicuriamoci di impostare la CPU su Intel Atom (x86) e spuntare l’opzione Use Host GPU.

[apache] Utilizzare ApacheBench per testare le performance del nostro server Apache

Anzitutto installiamo ApacheBench se non lo abbiamo già fatto, eseguendo il comando:

Normalmente Apache viene eseguito sulla porta 80 (http) e 443 (https), ma queste porte possono cambiare, come, per esempio, nel caso di una configurazione combinata con nGinx. Per scoprire su quali porte si trova Apache è sufficiente digitare da terminale:

Dovremmo vedere un output simile a questo:

In questo caso testiamo apache sulle porte 7080 e 7081.

Per lanciare il test digitiamo:

Questo eseguirà 500.000 richieste a pacchetti di 500 richieste per volta (richieste concorrenti). Il parametro -s 3600 imposta il timeout per l’esecuzione su 3600 secondi, mentre il valore predefinito è di 30 secondi.

Otterremo un risultato simile a questo:

Questo significa che per rispondere a 500.000 richieste al tasso di 500 richieste per volta, il server ha impiegato in tutto 25,163 secondi. Il tempo medio per ogni chiamata (500 richieste concorrenti) è di 25,163 millisecondi. Il tempo medio per ogni singola richiesta concorrente è quindi di 0,050 ms, dove 25,163ms / 500 = 0,050326 ms.

Adesso possiamo provare ad aumentare il carico sul server aumentando il numero di richieste concorrenti.

Il risultato sarà simile a questo:

Vediamo come il tempo per singola richiesta concorrente è passato da 0,050 ms a 0,660 ms. Il numero di richieste concorrenti è aumentato di 2 volte, mentre il tempo di risposta è aumentato di 13,2 volte.

Se proviamo ad eseguire invece 5.000 richieste concorrenti digitando:

Otterremo il seguente errore:

socket: Too many open files (24)

Questo significa che abbiamo superato il massimo numero di file aperti contemporaneamente e consentiti dal sistema. Tale configurazione dipende dalle configurazioni di sicurezza del sistema ed è modificabile in /etc/security/limits.conf

Digitiamo:

Dentro il file possiamo stabilire i singoli servizi quali limiti avranno, per aumentare il limite di tutti i servizi possiamo aggiungere in fondo al file:

Questo imposterà il limite al massimo valore consentito.

Se volessimo impostare il limite a 5000 file contemporanei dovremmo digitare ovviamente 5000.

Lo stesso risultato si può ottenere con:

Il comando non renderà la modifica persistente e al prossimo riavvio il valore tornerà a quello predefinito.

A questo punto possiamo ritentare il benchmark con:

Attenzione ad eseguirlo al netto del limite possibile, perché è probabile che si raggiunga la saturazione per via di altri file aperti quando si è prossimi al limite.

[mysql] Aumentare le performance del database MySQL

Questo esempio è sviluppato su un server Ubuntu con le seguenti caratteristiche:

32GB di RAM @2133 MHz, CPU Intel Xeon E3-1270v6 – quad core, 3,8GHz, 500GB disco SSD.

Le caratteristiche del server sono importanti, quanto il carico di lavoro che si intende sostenere per ottenere una giusta configurazione.

Prima di procedere oltre valutiamo anche lo stato iniziale del server ed eventualmente monitoriamo il carico di lavoro, per capire quanto margine abbiamo per le operazioni di calibrazione. A tale scopo ci saranno utili 2 programmi di Ubuntu.

Anzitutto usiamo htop per verificare l’uso di risorse della nostra macchina.

Se non dovessimo averlo installo eseguiamo:

Eseguendo htop da terminale dovremmo vedere una situazione simile a questa:

In questo caso possiamo notare che il server è scarico (in questo preciso momento).

Altro strumento che voglio utilizzare è mysqltuner. Questo ci permetterà di monitorare la situazione del server MySQL. Prima di lanciarlo è utile lasciare il server operativo per un tempo sufficiente (si parla di giorni o settimane, dipende dalla variabilità nell’utilizzo).

Se non disponiamo di mysqltuner installiamolo eseguendo:

Una volta eseguito, digitando semplicemente:

Vedremo un output con diverse statistiche e in fondo un elenco di raccomandazioni simile a questo:

A questo punto procediamo a modificare il file /etc/mysql/my.cnf impostando nuovi parametri (e poi provandoli).

Digitiamo dunque:

Andiamo ad impostare i seguenti parametri, di cui ne analizziamo alcuni:

innodb_buffer_pool_size

Questo parametro ci permette di impostare il pool del buffer. Il valore deve essere un multiplo del parametro innodb_buffer_pool_chunk_size moltiplicato per il parametro innodb_buffer_pool_instances. Il valore predefinito di innodb_buffer_pool_chunk_size è di 128MB, mentre innodb_buffer_pool_instances è impostato su 16.

Questo significa che un valore di 8GB per innodb_buffer_pool_size va bene, perché 8GB = 8192MB da cui 8192MB / ( 16 * 128MB ) = 4 (un numero intero).

Invece un valore di 15GB non andrebbe bene, perché 15GB = 15360MB da cui 15360MB / ( 16 * 128MB ) = 7,5 (un numero decimale).

query_cache_size

Il MySQL può tenere in cache le query già utilizzate, aumentando così notevolmente la velocità di esecuzione e le performance.

Anzitutto verifichiamo che la cache sia abilitata usando il commando:

Dopodiché possiamo impostare le seguenti variabili:

Le specifiche dimensioni dipendono dalla nostra disponibilità di RAM sul server.

max_connections

Questo parametro ci permette di stabilire il numero massimo di connessioni. Il valore predefinito è 150. Aumentando questo valore aumenterà il consumo di RAM.

Attenzione! Durante queste configurazioni assicuriamoci che la stima di memoria utilizzata da parte di mysqltuner non superi la massima memoria disponibile nel sistema, come in questo caso:

Entrambi i valori dovrebbero risultare OK, come nel seguente esempio:

Per fare una stima in anticipo sulle prestazioni possiamo usare il MySQL Calculator su questo indirizzo.

La precedente stima si ottiene sulla seguente configurazione di parametri:

Aumentando i valori naturalmente si aumenterà la quantità di risorse potenzialmente consumate dal database.

Una volta finite le modifiche al file my.cnf riavviamo il servizio MySQL digitando:

Come ultima operazione ottimizziamo il database, lanciando il seguente commando:

Se stiamo usando Plesk possiamo anche usare:

In questo modo la password dell’utente admin del database verrà prelevata dal file di configurazione di Plesk.

Fatto tutto questo monitoriamo il sistema e apportiamo eventuali correzioni.

[FIFA19] Crash DirectX function Dx12Renderer::waitOnSwapChain

In modo del tutto casuale durante il gioco (a me è successo con FIFA19, ma pare succeda anche con altri giochi tipo Battlefield) tutto si blocca con il seguente DirectX Error:

DirectX function “Dx12Renderer::waitOnSwapChain Gpu timeout detected” failed with DXGI_ERROR_DEVICE_HUNG. DirectX function “Dx12Renderer::waitOnSwapChain Gpu timeout detected” failed with DXGI_ERROR_DEVICE_HUNG. GPU: “”, Driver: 43648. This error is usually caused by the graphics driver crashing; try installing the latest drivers. Also, make sure you have a supported graphics card with at least 1024 MB of VRAM.

Inutile dire come la scheda video abbia 8GB di RAM e i driver siano aggiornati all’ultima versione (nel mio caso driver NVIDIA 436.48). Anche reinstallare i driver non sembra sortire alcun effetto e il problema sembra manifestarsi in modo del tutto casuale (anche se potrebbe essere collegato alla connessione col server, dal momento che ho notato che appare più frequentemente, tanto da rendere il gioco ingiocabile, quando la EA ha problemi coi server).

In ogni caso una soluzione che sembra funzionare consiste nell’apportare una modifica al registro di sistema, aumentando il tempo per il parametro Timeout Detection and Recovery. In pratica Windows tenta di verificare se la scheda video abbia completato o meno una certa operazione entro un tempo consentito (2 secondi); qualora questo non succeda si innesca il meccanismo di errore. Una più dettagliata spiegazione del fenomeno può essere trovata sul supporto Microsoft.

Per cercare di correggere il problema aumentiamo quindi il tempo del TDR nella maniera seguente.

  1. Premiamo Win+R e digitiamo regedit nella finestra Esegui. Premiamo OK e apriamo il Registro di sistema.
  2. Posizioniamoci in Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers
  3. Nel riquadro sulla destra clicchiamo con il tasto destro del mouse e creiamo una nuova chiave di tipo QWORD (per i computer a 64bit)
  4. Come nome della chiave digitiamo TdrDelay
  5. Clicchiamoci due volte sopra ed inseriamo 10 come valore decimale (altrimenti la lettera a come valore esadecimale) in modo da aumentare il tempo a 10 secondi (possiamo anche aumentare il valore maggiormente nell’eventualità di altri problemi)
  6. Chiudiamo il registro di configurazione e riavviamo il computer, in modo da ricaricare il registro (in teoria sarebbe sufficiente riavviare esplora risorse)

Fatto questo il problema non dovrebbe più presentarsi.

Nel caso che il problema non si fosse ancora risolto possiamo provare a modificare le Impostazioni 3D per il gioco (questo per i possessori di una NVIDIA).

Procediamo nella maniera seguente:

  1. Clicchiamo col destro sul desktop e scegliamo Pannello di controllo NVIDIA
  2. Andiamo su Impostazioni 3D > Gestisci le impostazioni 3D
  3. Apriamo la scheda Impostazioni programma e selezioniamo FIFA 19
  4. Modifichiamo le seguenti voci:
    Sincronizzazione verticale: Usa l’impostazione dell’applicazione 3D
    Tecnologia monitor: Aggiornamento fisso
    Velocità di aggiornamento preferita: La più elevata disponibile
  5. Premiamo sul tasto Applica

Il crash sulle DirectX 12 sembra infatti legato alla tecnologia G-SYNC dei monitor NVIDIA.

[wordpress] Aggiungere un utente amministratore programmaticamente

Per creare un utente amministratore per il nostro sito di WordPress utilizzando solo il codice di programmazione (immaginiamo per esempio di aver dimenticato l’utente principale e non voler fare modifiche sul database, dove per altro sarebbe ancora più facile), è sufficiente procedere nella maniera seguente.

Apriamo il file functions.php che si trova nella cartella del tema, tipicamente in /wp-content/themes/

In fondo al file aggiungiamo il seguente pezzo di codice:

A questo punto eseguiamo una qualunque pagina del sito, per esempio la home page, ed il gioco è fatto. 🙂