Chiamiamo da C# un programma IBM-i nativo tramite WinSCP/SSH

Chiamare un programma nativo IBM-i (o AS400) da Windows fuori dall’emulatore e con soluzioni automatizzate è sempre stato un incubo: Molti nel tempo hanno sviluppato soluzioni basate sulla DLL di Client Access cwbx.dll, che purtroppo ad oggi è considerata deprecata. Molti hanno preferito usare OleDB con moltissimi limiti (ad esempio non è possibile passare parametri). Altri temerari hanno intrapreso invece lo sviluppo di WS appositi o l’uso di JT400 (ed a loro va tutto il mio rispetto!).

C’è un altro metodo, molto semplice e performante per far iteragire Windows ed il nostro monolite preferito: WinSCP ed SSH!

Perchè chiamare un programma IBM al di fuori del terminale?

In sistemi informativi complessi spesso è necessario far interfacciare componenti Legacy con applicazioni windows.
Orchestrare una serie di programmi/iterazioni complesse, schedulare applicazioni in catene e far comunicare applicazioni differenti è una delle sfide giornaliere che devono affrontare i i system integrator e gli architect solutions.

Prerequisiti

Sul sistema target deve essere presente SSH (il componente è 5733-SC1 Licensed Program Product) configurato e funzionante. Una credenziale d’accesso ed un collegamento aperto sulla porta.

WinSCP e .NET

Molti di voi conoscono WinSCP come un software molto utile per fare file-transfer come alternativa di Filezilla ma in pochi sanno che nella cartella del programma c’è una magnifica DLL, winscpnet.dll che può essere referenziata in un progetto .NET.
Di setuito, un elenco di esempi presi dal sito ufficiale:
Documentazione .net: https://winscp.net/eng/docs/library

Esempio di chiamata in C#

Di seguito il POC da cui sono partito. Io per semplificarmi le cose ho messo parte delle configurazioni in un config file:

using System;
using WinSCP;
using System.Configuration;    
using System.Xml;
using System.Xml.Serialization;
class Programma

{
    public static int Main()
    {
        string server = ConfigurationManager.AppSettings["server"];
        string SshHostKeyFingerprint = ConfigurationManager.AppSettings["SshHostKeyFingerprint"];
        string UserName = ConfigurationManager.AppSettings["UserName"];
        string password = ConfigurationManager.AppSettings["password"];
        string SshPrivateKey = ConfigurationManager.AppSettings["SshPrivateKey"];
        string SshPrivateKeyPassphrase = ConfigurationManager.AppSettings["SshPrivateKeyPassphrase"];
        string LogPath = ConfigurationManager.AppSettings["LogPath"];

        try
        {
            // Setup session options
            SessionOptions sessionOptions = new SessionOptions
            {
                Protocol = Protocol.Sftp,
                HostName = server,
                UserName = UserName,
                //Password = password,
                SshPrivateKeyPath = SshPrivateKey,
                PrivateKeyPassphrase = SshPrivateKeyPassphrase,
                SshHostKeyFingerprint = SshHostKeyFingerprint
            };

            using (Session session = new Session())
            {
                // Connect
                session.SessionLogPath = LogPath;

                session.Open(sessionOptions);

                string CommandAS400 = string.Format(@"system ""CALL PGM(LIBRERIA/PROGRAMMA) PARM('PARAMETRO')""");
                string output;
                output = session.ExecuteCommand(CommandAS400).Output.ToString();
            }

            return 0;
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: {0}", e);
            return 1;
        }
    }
}

Analizziamo il programma nelle componenti su cui prestare attenzione:
La sezione di SessionOptions raccoglie tutte le informazioni di connessione:

Protocol: Protocol.Sftp Questo è un valore fisso
HostName: Nome del server o il suo IP
UserName: Login AS400
Password: Password AS400
SshHostKeyFingerprint: Chiave pubblica del server

In alternativa alla password è possibile usare una chiave privata SSH:

SshPrivateKeyPath: Posizione del file PPK contenente la chiave privata
PrivateKeyPassphrase: Eventuale password della chiave privata

il blocco successivo contiene la chiamata:

il comando va costruito così:

system ""CALL PGM(LIBRERIA/PGM) PARM('PARM')""

La chiamata sfrutta il comando QSH System che permette di chiamare da console POSIX i comandi e programmi di sistema della CLI nativa del sistema operativo.
Invece tramite questo statement:

output = session.ExecuteCommand(CommandAS400).Output.ToString();

Permette di intercettare l’output del programma.
– Se il chiamato è un CLP, può essere usato il comando SNDPGMMSG  MSG(&MSG1)
– Se il chiamato è uno script SH, viene wrappato lo STDout

Usando questo statement poi

session.SessionLogPath = LogPath;

è possibile loggare in maniera molto dettagliata il log di connessione, utile per fare eventuale troubleshooting.

Conclusione

La soluzione si presta per molti scenari, personalmente la uso per chiamare programmi da SSIS o per gestire schedulazioni centralizzate ed orchestrate.

Powershell in un job MSSQL – Error logging – Gestiamo gli errori con le funzioni standard di SQL

Nella cassetta degli attrezzi di un sistemista che si rispetti non può mancare Powershell.
Io personalmente lo adoro e mi permette di automatizzare molti task sistemistici.

Qui sotto riporto un piccolo esempio per integrare uno script Powershell in un job SQL:

$ErrorActionPreference = "Stop"
try{

QUI IL MIO CODICE O LA CHIAMATA AL MIO PS1  

   }
catch{
   Throw
}

Impostato in questa maniera, siamo in grado di intercettare nel job history di SQL le eventuali eccezioni ed errori del nostro script, cosa molto utile se lo si schedula in orario non lavorativo, con alerting automatico in caso di abend (Abnormal End)

Microsoft SQL – Database in AAG – Abilitiamo o disabilitiamo servizi Windows sui nodi

Quella del cluster database di tipo AAG (Always-on Availability Group) è una delle configurazioni più resilienti di SQL e tramite una configurazione a nodo 1+N che se bilanciata bene permette una grossa resilienza ed un importante uptime.

Introduzione

Nell’AAG, uno dei nodi è sempre il primario, i “+N” (che potrebbe essere uno o molteplici) rimangono in standby con una replica puntuale dei DB. Una delle caratteristiche più interessanti della configurazione AAG è il failover automatico, che consiste nel cambio ruolo automatico a fronte di un problema tecnico. In questo scenario potrebbe essere necessario attivare dei servizi ancillari alla macchina, come ad esempio uno schedulatore esterno (es IWS), uno strumento di file transfer o un qualsiasi agent.

Esempio di TSQL per Avviare o Arrestare dinamicamente un servizio in base al nodo in cui sta girando l’istanza

di seguito, un piccolo POC con un esempio di TSQL per avviare o disabilitare un servizio a fronte di un cambio ruolo di SQL:

DECLARE @primreplica VARCHAR(100);
DECLARE @ServiceName VARCHAR(128) = 'NOMESERVIZIO';
DECLARE @Status VARCHAR(MAX);

    DECLARE @ServicesStatus TABLE
    (
        Status VARCHAR(50)
    );

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)
BEGIN

    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

END;

ELSE
BEGIN
    INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status = 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Stop', @ServiceName;
    END;

END;

Personalmente, l’ho schedulato in un job SQL sempre attivo su tutti i nodi (lo stesso JOB contiene lo statement per abilitare o disabilitare i JOB SQL).

Andiamo un poco più in drill-down:
Tramite la select di seguito riportata, stabilisco se sto girando sulla replica primaria o sul secondario, andando a confrontare il nome del server su cui sta girando l’istanza (tramite la funzione SQL @@SERVERNAME) ed il nome della replica primaria sulle tabelle di sistema che regolano l’AAG:

SELECT @primreplica = s.primary_replica
FROM sys.dm_hadr_availability_group_states s
    JOIN sys.availability_groups ag
        ON ag.group_id = s.group_id;

-- se dove sto girando è primario
IF UPPER(@primreplica) = UPPER(@@SERVERNAME)

Con un semplice ciclo IF/ELSE tramite una tabella di appoggio e la StoreProcedure EXEC xp_servicecontrol determino se il servizio sta girando o meno ed in base alla risposta ed al server, avvio o disabilito il servizio:

INSERT @ServicesStatus
    EXEC xp_servicecontrol N'QUERYSTATE', @ServiceName;

    SELECT @Status = Status
    FROM @ServicesStatus;
    --select @Status

    IF @Status <> 'Running.'
    BEGIN
        EXEC xp_servicecontrol N'Start', @ServiceName;
    END;

Sintassi di xp_servicecontrol

EXEC xp_servicecontrol ‘Querystat|Start|Stop’,’servicename’

La store in oggetto accetta due parametri, il primo è l’operazione da svolgere:

  • Querystat – Restituisce lo stato di un servizio.
  • Start – Avvia un servizio.
  • Stop  – Arresta un servizio.

Il secondo, il nome del servizio.

Enjoy!

Scarichiamo su una tabella MS-SQL i dati degli utenti Active Directory leggendoli sempre da una tabella

Se fai il sistemista e ti diverti a fare reportistica ed incrociare dati tra gli applicativi aziendali e Active Directory, questo è lo script che fa per te.

Lo script powershell sfrutta i seguenti CMDlet:
DBAtools (https://dbatools.io/)
GetADUSER di Microsoft (https://4sysops.com/wiki/how-to-install-the-powershell-active-directory-module/)

Lo script è stato customizzato per essere configurato facilmente e l’ho creato per le mie esigenze.

In breve lo script:
– Legge una tabella con le utenze AD;
– Crea se non esiste la Tabella coi dati di AD
– Interroga AD e memorizza le info in una nuova tabella

Io metto sempre Integrated Security = True per usare l’identity SQL di chi esegue lo script.

$SQLDB = 'IP DEL DB'
$DB = 'NomeDatabase'
$TABLE = 'Tabella da scrivere'
$TABLESRC = 'Tabella da leggere'

$connString = "Server = " + $SQLDB + "; Database = " + $DB +  "; Integrated Security = True"
$QueryText = "SELECT [UTENZAACTIVEDIRECTORY] FROM " + $DB + ".[dbo]." + $TABLESRC

$SqlConnection = new-object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = $connString
$SqlCommand = $SqlConnection.CreateCommand()

$SqlCommand.CommandText = $QueryText

$DataAdapter = new-object System.Data.SqlClient.SqlDataAdapter $SqlCommand
$dataset = new-object System.Data.Dataset
$DataAdapter.Fill($dataset)

$dataset.Tables[0] | ForEach {

$DataTable = Get-ADUser -identity $_.matricola.Trim() -Properties * |select samaccountname , surname, givenname, mail ,department, enabled |Where-Object {$_.LastLogonDate -ge (get-date).adddays(-400)} | ConvertTo-DbaDataTable
Write-DbaDataTable -SqlInstance $SQLDB -Database $DB -InputObject $DataTable -Table $TABLE -AutoCreateTable
}

Ovviamente è un esempio, con Get-ADUser possono essere fatte centinaia di altre operazioni. Inoltre lo script può essere schedulato su un server, eseguirlo in interattivo o inserirlo in un JOB SQL per un report.

Chiamare da un CL IBMi uno script SH e ricevere un output da esso

CLP (Control Language Program) è un linguaggio di scripting eccezionalmente potente che permette di automatizzare operazioni su IBM-i (conosciuto anche come AS400).

Seppur potente, non copre proprio tutto tutto, e spesso va affiancato ad altri strumenti quali script SH *nix-like, che permette a chi viene da sistemi Linux o Unix di poter creare cose molto interessanti.

Qui di seguito un esempio di programma che intercetta l’output di uno script SH che può essere utilizzato come variabile all’interno di un programma CLP:

PREMESSA: sulla macchina deve essere presente 5770-SS1 – Portable Application Solutions Environment.

Per intercettare il STDOUT va creata una variabile di sistema tramite il comando:

ADDENVVAR ENVVAR(QIBM_QSH_CMD_OUTPUT)  VALUE(STDOUT) LEVEL(*JOB)

Esempio di programma:

PGM                                               
DCLF       FILE(QTEMP/O1)                         
DLTF       FILE(QTEMP/O1)                         
MONMSG     MSGID(CPF2105)                         
CRTPF      FILE(QTEMP/O1) RCDLEN(1000)            
OVRDBF     FILE(STDOUT) TOFILE(QTEMP/O1)          
STRQSH     CMD('SH path dello script')
DLTOVR     FILE(*ALL)                             
RCVF                                              
MONMSG     MSGID(CPF0864)                         
SNDPGMMSG  MSG(&O1)  
ENDPGM                                            

Questo esempio:
– scrive sul file QTEMP/O1 tramite OVRDBF l’output dello script SH
– tramite RCVF del file QTEMP/O1 può essere letto il campo appena scritto come variabile &O1

Letteratura a supporto

https://www.ibm.com/docs/en/i/7.2?topic=reference-calling-qshell-commands-from-i-command-line

https://www.ibm.com/docs/en/i/7.3?topic=i-installing-pase

LifeHack – Trasformiamo il sensore della porta WIFI in un telecomando per automazione domotica

Ciao a tutti oggi vi mostreremo come trasformare un economico sensore da porta in un telecomando per automazione wifi.

Di seguito il link al video: https://youtu.be/ppTtRBeBr2c

Normalmente questi sensori vengono applicati a porte e finestre per notificare l’apertura/chiusura o eventualmente per funzionare da trigger per automatizzare l’accensione di una luce o come antifurto.

Il sensore che ho acquistato è molto economico (circa 11 euro) ed è acquistabile su Amazon al seguente link: https://amzn.to/3s7M8Xp

Io uso prettamente apparati Tuya (SmartLife), la stessa procedura può essere svolta anche su Sonoff ed altri. il funzionamento è il medesimo.

Nella parte fissa del sensore (quella che per intenderci è dotata di batterie) è presente un componente chiamato “contatto REED”. Questo non è altro che un interruttore a lamina (normalmente aperto) che si chiude in presenza di un campo magnetico.

Facendo una rapida prova con il test impostato su continuità, possiamo osservare che avvicinando il magnete, il REED si chiude come un pulsante.

Armandoci di buona pazienza e di un saldatore, andiamo a rimuovere il REED (conservandolo magari per un futuro uso) e sostituiamolo con un pulsante a nostra scelta. io ne avevo uno di recupero simile a quello di reset, che ho spostato per usare il pulsante originale come trigger.

Ecco il circuito modificato

Una rapida prova prima di richiudere tutto

Infine la versione assemblata!

Ovviamente il tasto ora è da configurare sulla piattaforma del produttore (SmartLife, Ewelink, ecc ecc), oppure sull’assistente vocale preferito.

Le applicazioni sono molteplici, è possibile usarlo come campanello, come telecomando per accendere e spegnere dispositivi domotici, ecc ecc.

Kodi su Firestick – Canali del Digitale Terrestre

UPDATE 20210922 – Pubblicato il video sul canale Youtube: https://youtu.be/-4pluvobJG0

La Firestick Amazon è una vera e propria rivoluzione copernicana.
Questo articolo illustrerà come installare Kodi e gli addon necessari per vedere i canali del Digitale Terrestre.

La procedura è legale solamente se viene utilizzata per vedere canali in chiaro.

Per prima cosa abilitiamo da impostazioni > La mia Fire TV

Opzioni Sviluppatore

e mettiamo su ON le Applicazioni da fonti sconosciute

La fire chiederà di confermare l’opzione.

Attenzione: L’applicazione che vi indicheremo è abbastanza sicura e collaudata. Installate con giudizio le applicazioni esterne allo store. Una applicazione contenente un componente corrotto o virato potrebbe compromettere la stick!

Una volta abilitata la funzione, andremo ad installare il browser “Downloader” da Applicazioni > Categorie > Utility.

“Downloader” permette di scaricare da internet facilmente file sulla firestick

Terminata l’installazione dobbiamo lanciare la APP tramite la Homepage di FireStick

Aperta la mappa del software va cliccando sul campo di input

inseriremo l’indirizzo http://www.kodi.tv/download

Quando la pagina si caricherà sulla pagina richiesta

Va cercato il link della applicazione per Android

e scaricata la versione per ARM a 32 bit

una volta scaricato il file, partirà automaticamente l’installer

Scorrendo sulla mappa, apparirà il tasto Install

Premendolo partirà la vera e propria installazione. Una volta terminata l’installazione, sarà possibile aprire Kodi.

Lanciato Kodi, va aperta la mappa delle impostazioni per aggiungere una fonte da cui scaricare gli Add-ons

clicchiamo su File Manager

e su Add Source

Dalla mappa Add File Source va cliccato su <None>

inserito l’indirizzo https://worldlivetv.github.io/repo

e dato un nome parlante alla sorgente nel campo Enter a name for this media source

Aggiunta la Source, va selezionato Add-ons

selezionato Install from zip file

per motivi di sicurezza, l’installazione di add-ons esterni è inibito.
Va modificato il parametro premendo il tasto Settings

sotto Add-ons va abilitato Unknown source

Dato che andremo ad inserire un add-on sicuro, premere si.

Tornato sulla mappa, selezioneremo il repository con il nome parlante indicato su Add File Source

e scaricheremo/installeremo il file ZIP.

Quando apparirà il popup

Sara possibile accedere da Add-ons al repository di WorldLive TV

Da qui, da Video Add-ons

Dovremo selezionare World Live TV Helper

ed installarlo.

Terminata l’installazione, Kodi ci informerà con un popup che il componente richiesto è stato installato.

Selezioniamo poi dalla homepage di Kodi Add-ons

Video Add-ons

World Live TV Helper

Selezioniamo Select List

e procediamo con l’installazione dell’ultimo componente necessario, il PVR IPTV Simple Client indispensabile per avere l’elenco dei canali sulla voce TV della Homepage

Infine, dobbiamo selezionare dall’elenco FTA

Una volta installato tutto, sarà possibile goderci i canali del Digitale terrestre senza dover usare un decoder o una antenna tv

Enjoy!

tommy@madlabs.org

VBSCRIPT – Zippare ed Unzippare con 7z

In ambito sistemistico, a volte è utile avere tra le proprie armi una funzione per lavorare con i file ZIP. vi allego un comodo esempio da includere nei vostri script

Chiamata alla funzione

    ReturnCode = UnZip(“w:\file*.zip”, ”W:\CartellaOut\”)
    WScript.Echo ”ZIP ” & returnCode

    ReturnCode = Zip(“w:\file*.txt”, ”W:\CartellaOut\file.zip”)
    WScript.Echo ”ZIP ” & returnCode

Ponendo come riportato qui sopra, la funzione restituisce il return code.

Codice di Esempio

Le funzioni sono due: zip ed unzip

Function Zip(sFile,sArchiveName)

  Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
  Set oShell = WScript.CreateObject("Wscript.Shell")

  '--------Find Working Directory--------
  aScriptFilename = Split(Wscript.ScriptFullName, "\")
  sScriptFilename = aScriptFileName(Ubound(aScriptFilename))
  sWorkingDirectory = Replace(Wscript.ScriptFullName, sScriptFilename, "")
  '--------------------------------------

  '-------Ensure we can find 7z.exe------
  If oFSO.FileExists(sWorkingDirectory & "\" & "7z.exe") Then
    s7zLocation = ""
  ElseIf oFSO.FileExists("C:\Program Files\7-Zip\7z.exe") Then
    s7zLocation = "C:\Program Files\7-Zip\"
  Else
    Zip = "Error: Couldn't find 7z.exe"
    Exit Function
  End If
  '--------------------------------------

  oShell.Run """" & s7zLocation & "7z.exe"" a -tzip -y """ & sArchiveName & """ " _
  & sFile, 0, True   

  If oFSO.FileExists(sArchiveName) Then
    Zip = 1
  Else
    Zip = "Error: Archive Creation Failed."
  End If
End Function

Function UnZip(sArchiveName,sLocation)

  Set oFSO = WScript.CreateObject("Scripting.FileSystemObject")
  Set oShell = WScript.CreateObject("Wscript.Shell")

  '--------Find Working Directory--------
  aScriptFilename = Split(Wscript.ScriptFullName, "\")
  sScriptFilename = aScriptFileName(Ubound(aScriptFilename))
  sWorkingDirectory = Replace(Wscript.ScriptFullName, sScriptFilename, "")
  '--------------------------------------

  '-------Ensure we can find 7z.exe------
  If oFSO.FileExists(sWorkingDirectory & "\" & "7z.exe") Then
    s7zLocation = ""
  ElseIf oFSO.FileExists("C:\Program Files\7-Zip\7z.exe") Then
    s7zLocation = "C:\Program Files\7-Zip\"
  Else
    UnZip = "Error: Couldn't find 7z.exe"
    Exit Function
  End If
  '--------------------------------------

  '-Ensure we can find archive to uncompress-
  If Not oFSO.FileExists(sArchiveName) Then
    UnZip = "Error: File Not Found."
    Exit Function
  End If
  '--------------------------------------

  oShell.Run """" & s7zLocation & "7z.exe"" e -y -o""" & sLocation & """ """ & _
  sArchiveName & """", 0, True
  UnZip = 1
End Function

Una GUI per i nostri script VBScript

Esempio di GUI

VBScript sta per Visual Basic Scripting ed è come dice il nome un linguaggio di scripting multi-purpose. Questo è un derivato diretto di Visual Basic, ed è usato come sostituto, integrazione o appoggio per i file batch di MS-DOS .

Come tutti i linguaggi di scripting, non ha GUI nativa. Ma con un piccolo amico, l’HTA (Hypertext for Application) è possibile creare delle vere e proprie applicazioni =)

Un HTA non è altro che un file HTML arricchito con uno script VBS. Possono essere aggiunti JS, CSS, popup, campi di input ed altri elementi utili per creare un capolavoro.

Questo è un esempio di applicazione con tabs:

<html>
      <head>
            <title>Questa è una prova di GUI per gli script VBScript</title>
            <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css" />
            <script language="javascript" src="http://code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
            <script language="javascript" src="http://code.jquery.com/ui/1.10.4/jquery-ui.js" type="text/javascript"></script>
            <script language="javascript">
                  try {
                        self.resizeTo(1030, 600);
                   } catch(e) {
                   }
            </script>
            <hta:application
                  SINGLEINSTANCE="yes"
                  MAXIMIZEBUTTON="yes"
            >
      </head>
      <script language="VBScript">
      
      	<<<<<QUI METTI IL CODICE VBScript>>>>>
      
Sub Window_OnLoad
	<<<<<QUI METTI IL CODICE DA ESEGUIRE ALLA PARTENZA>>>>>
End Sub

Sub NomeSub( )
      
      	<<<<<QUI METTI IL CODICE della subroutineVBScript>>>>>
      
End Sub
</script>
   
      <body>
            <div id="tabs">
                  <ul>
                  <li><a href="#fragment-1">Username</a></li>
                  <li><a href="#fragment-2">User Definition</a></li>
                  <li><a href="#fragment-3">Group Domain</a></li>
                  <li><a href="#fragment-4">Create Ticket</a></li>
                  <li><a href="#fragment-5">Provvisioning</a></li>
                  <li><a href="#fragment-6">Test Linux</a></li>
                  </ul>
                  <div id="fragment-1"><br><br>Questa è una prova di GUI </div>
                  <div id="fragment-2">Prova2</div>
                  <div id="fragment-3">Prova3</div>
                  <div id="fragment-4">Prova</div>
                  <div id="fragment-5">Provvisioning</div>
                  <div id="fragment-6">TestLinux</div>
            </div>
            <script>
                  $("#tabs").tabs();
            </script>
      </body>
</html>

L’applicazione può eseguire un solo script o varie sub-routine.
Per creare una prima applicazione, basta copiare ed incollare questo src su un notepad e salvare il file come .HTA

Per chi è alle prime armi, esiste un fantastico strumento (sviluppato anch’esso in VBS e HTA) che riunisce la gran parte delle operazioni di input ed output, HTA HELPOMATIC degli Scripting Guy.

Vi posterò presto il link per scaricarlo, dato che sono anni che non si trova.

Se vi è piaciuto l’articolo, fatemelo sapere con un commento =)

Vostro Tommy – tommy [@] madlabs.org

Che figata! caricare contenuti sul Kindle è facile come mandare una e-Mail

Ciao Sbabbari, Ho avuto il piacere di avere tra le mani un Amazon Kindle nuovo di pacca, che un amico mi ha chiesto di comprargli approfittando del prime-day. Premetto che possiedo da molto tempo un lettore simile della Sony, che è lontano anni luce da quello del colosso guidato da Jeff Bezos.

Con il mio fedelissimo Sony sono abituato a spostare tutto tramite Esplora Risorse del pc o su di una SD, quindi la prima cosa che ho fatto OoB è stato collegare il dispositivo al mio computer, ma tranne che per il led di carica, il collegamento non ha sortito effetto alcuno.

Quindi, come caricare file differenti da quelli acquistati sullo store della casa madre? Semplicissimo, basta mandare una mail al dispositivo!

Accedendo al sito www.amazon.it/myk è possibile attivare il servizio Documenti Personali, che permette di caricare tramite una semplice mail contenuti testuali quali:

  • Mobi (Formato per eBook)
  • Microsoft Word (.doc, .docx)
  • Rich Text Format (.rtf)
  • HTML (.htm, .html)
  • Documenti di testo (.txt)
  • Documenti archiviati (zip , x-zip) e documenti archiviati compressi
  • Immagini nei formati: JPEG (.jpg), GIF (.gif), Bitmap (.bmp) e PNG (.png).
  • documenti in formato Adobe PDF (.pdf)

La funzione è abilitabile alla voce Preferenze

Abilitando il servizio, Amazon creerà una casella di posta di servizio @kindle.com. Questa non sarà una vera e propria mailbox, ma solamente una casella postale tecnica di sola ricezione. Per creare un indirizzo univoco, viene preso l’alias della mailbox con cui si è registrati su Amazon, al netto del dominio, con l’aggiunta di una serie di lettere casuali per garantirne l’univocità. Consiglio di modificarla con una cosa più semplice ed intuitiva (Nel nostro caso è bastato rimuovere i caratteri supplementari per avere equipollenza tra l’alias della mailbox e quello dell’indirizzo Kindle.

Per evitare spam ed abusi, solo le caselle autorizzate in White-list hanno il consenso per il caricamento di contenuti sul dispositivo.

Da qui premendo il link evidenziato in giallo è possibile inserire un nuovo indirizzo mittente autorizzato in White List

Quindi, per inviare un proprio eBook, un PDF o un qualsiasi altro tipo di documento, basta allegarlo ad una mail indirizzata alla casella @kindle.com.
Possono essere inviati fino a 25 file per messaggio e salvo errori, i file verranno caricati sul cloud di Amazon e scaricati sul dispositivo.

Elenco dei file personali – menù Contenuti -> Documenti

Semplicissimo no?

Se si desidera invece organizzare la propria libreria digitale ed avere uno strumento tout cour per la gestione dei file e la trasmissione a Kindle potete provare anche ad usare Calibre (Open Source: https://calibre-ebook.com/download)

Tommy
Tommy[at]madlabs.org