martedì 26 settembre 2006
Come trovare le informazioni del sistema
Nei sistemi Win32, esiste l’API GetVersionEx che restituisce le informazioni nella struttura OSVERSIONINFO. Quindi possiamo guardare i valori di tutti i vari campi della struttura ed analizzare tutto (o quasi!!) del sistema operativo in esecuzione.
Il Framework 2005 ci fornisce la classe Environment. Questa classe contiene un metodo chiamato OSVersion che restituisce l’oggetto OperatingSystem. Quest’oggetto può essere utilizzato per fornire informazioni sulla versione del sistema.
Come ottenere l’oggetto OperatingSystem
La classe OperatingSystem contiene tre proprietà:
- Platform: restituisce il valore del PlatformID.Ha tre differenti valori.
- Win32NT àWindows NT
- Win32Windows à Windows 95 o superiore
- Win32S à Win32s è in esecuzione su una versione a 16-di Windows.
2. CSD: questa proprietà indica il numero Corrected Service Diskette del sistema operative o in alter parole la stringa che rappresenta la service pack installata.
- Version: Restiruisce la versione. Questa classe è vuota, ma la classe Version standard usata per indicare la versione di qualsiasi assembly in .NET definisce un insieme di valori indicati come Major.Minor.Revision.Build. La classe Version contiene, infatti, 4 proprietà che restituiscono completamente le informazioni del sistema operativo.
- Major – Numero della Major Version
- Minor - Numero della Minor Version
- Revision - Numero della Revision
- Build - Numero della Build
Cosa significano questi valori???
Combinando tre dei valori restituiti otterremo l’esatta versione del sistema operative utilizzato. Nella tabella seguente elenco i possibili risultati che possiamo ottenere dalla combinazione dei valori ottenuti.
|
PlatformID
|
Major Version
|
Minor Version
|
Sistema Operativo
|
|
Win32Windows
|
>= 4
|
0
|
Win95
|
|
Win32Windows
|
>= 4
|
> 0 AND < 90
|
Win98
|
|
Win32Windows
|
>= 4
|
> 0 AND >= 90
|
WinMe
|
|
Win32NT
|
<= 4
|
0
|
WinNT
|
|
Win32NT
|
5
|
0
|
Win2K
|
|
Win32NT
|
5
|
> 0
|
WinXP
|
Nel codice seguente invece una breve descrizione Following a small sample from the class that shows the use of Environment class in System namespace.
Dim os As OperatingSystem = Environment.OSVersion
' Prendiamo le informazioni della versione
Dim vs As Version = os.Version
Private Me.m_nMajorVer = vs.Major
Private Me.m_nMinorVersion = vs.Minor
Private Me.m_nRevision = vs.Revision
Private Me.m_nBuildNumber = vs.Build
' Prendiamo le informazioni della service pack
Private Me.m_strServicePack = os.ServicePack
Ciao
Ivan
lunedì 24 luglio 2006
L’utilità di scaricare aggiornamenti di un software da un proprio server e memorizzarli da quale altra parte in locale, specificando il percorso, è una possibilità che ci viene offerta dal Metodo My.Computer.Network.DownloadFile.
Le proprietà Username e Password permettono di impostare le credenziali d’accesso al server. E’ possibile anche impostare il parametro ShowUI a True per fare in modo che venga visualizzata una finestra nella quale sono contenute lo stato di avanzamento del download e la possibilità di annullare l’operazione.
Per verificare l’esistenza di una connessione possiamo assegnare un valore al parametro ConnectionTimeOut.
Può anche succedere di voler sovrascrivere il file, qualora esistesse già in locale, impostando Overwrite su True.
Quindi il metodo può assumere differenti aspetti:
1 - My.Computer.Network.DownloadFile ("http://www.sbsoft.it/downloads/Download.txt", "C:\Documents and Settings\All Users\Documents\DownloadTest.txt"), con URL e Path dove salvare il file;
2 - My.Computer.Network.DownloadFile ("http://www.sbsoft.it/downloads/Download.txt", "C:\Documents and Settings\All Users\Documents\DownloadTest.txt","ivan","sbsoft"), con l’aggiunta di Username e Password;
3 - My.Computer.Network.DownloadFile ("http://www.sbsoft.it/downloads/Download.txt", "C:\Documents and Settings\All Users\Documents\DownloadTest.txt","ivan","sbsoft",True,500,True), con Interfaccia di download, Tempo di connessione e Flag di sovrascrittura.
OKKIO!!! Alcune eccezioni che possono essere generate sono:
- Unità non valida;
- Username e Password errate;
- ConnectionTimeOut scaduto;
- Richiesta rifiutato dal sito web.
Ciao
Ivan
?>
mercoledì 12 luglio 2006
Molto spesso abbiamo bisogno di inserire oggetti (immagini, file di testo, filmati Flash, ecc …) e di richiamarli in fase di esecuzione. Il problema può essere risolto in due modi:
1 – Portandoci dietro il file originale;
2 – Includendo il file nel nostro progetto e compilarlo con esso.
La prima soluzione non staremo qui a spiegarla e presteremo molta attenzione alla seconda soluzione.
Il framework .NET (già dalla versione 1.1) ci permette di memorizzare, all'interno di un progetto, qualsiasi tipo di file.
Per fare ciò è necessario:
1) importare il file all'interno del progetto utilizzando il menù Project\Add Existing Items;
2) selezionare il file all'interno del Solution Explorer e impostare tra le proprietà la Build Action come Embedded Resource;
In questo modo il nostro file EXE verra compilato direttamente don il progetto.
A questo punto non ci rimane altro che richiamare il file in fase di esecuzione. Per fare questo possiamo utili il codice seguente:
Private bmStop As Bitmap
Dim a As Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
bmStop = New Bitmap(a.GetManifestResourceStream( "NamSpaceRadice.NomeFile.Est"))
NameSpaceRadice è il nome del namespace root dell'assembly mentre NomeFile.Est è il nome del file inserito nel progetto.
N.B.
Il metodo GetManifestResourceStream genera un'eccezione se il file e di dimensioni superiori ai 2GB
Ciao
Ivan
?>
domenica 19 marzo 2006
Inviare e-mail nel Framwork 2.0 è quasi la stessa cosa della versione 1.0. Ci sono solo un paio di varianti.
La prima differenza è ne fatto che tutte le funzionalità sono incluse nel nuovo namespace System.Net.Mail e non più nel System.Web.Mail.
L'altra è da cercare nel codice seguente:
MailMessage oMsg = new MailMessage();
//Imposta il mittente
oMsg.From = new MailAddress("ivan.gentile@sbsoft.it", "Ivan Ufficio");
//La proprietà .To è una collezione di destinatari,
//quindi possiamo addizionare quanti destinatari vogliamo.
oMsg.To.Add(new MailAddress("ivan.gentile@libero.it","Ivan Casa"));
//Imposto oggetto
oMsg.Subject = "Prova E-Mail via .Net";
//Imposto contenuto
oMsg.Body = "Ci sono riuscito!!!";
oMsg.IsBodyHtml = true;
//Imposto il Server Smtp
SmtpClient oSmtp = new SmtpClient("smtp.server.com");
//Possiamo impostare differenti metodi di spedizione.
//Imposta consegna diretta.
oSmtp.DeliveryMethod = SmtpDeliveryMethod.Network;
//Alcuni Server SMTP richiedono l'accesso autenticato
NetworkCredential oCredential = new NetworkCredential("username","password");
oSmtp.UseDefaultCredentials = false;
oSmtp.Credentials = oCredential;
//Spediamo la mail
oSmtp.Send(oMsg);
Consiglio di impostare tutto in un blocco Try Catch dal momento che i motivi che generano eccezzioni sono diversi come: indirizzo e-mail errato, errori di autentificazione, problemi di rete, ecc...
Per chi volesse utilizzare questo codice in ASP.Net:
Dim oMsg As MailMessage = New MailMessage()
oMsg.To.Add(ivan.gentile@sbsoft.it)
oMsg.From = New MailAddress(ivan.gentile@sbsoft.it)
oMsg.Subject = "Prova"
oMsg.Body = "FATTO!!!"
Dim oSmtp As SmtpClient = New SmtpClient("smtp.server.com")
oSmtp.Send(oMsg)
Okkio le parole in rosso devono essere adattate in base al server smtp utilizzato.
Ciao
Ivan
giovedì 16 marzo 2006
Quando lavoriamo con ASP.Net 2.0 e le Master Pages accade un qualcosa di particolare.
ASP.Net rinomina automaticamente tutti gli ASP Controls inseriti all'interno della Master Page per evitare problemi di replicazione dei nomi.
Vi garantisco che è impossibile assegnare ad un ASP Control un ID, dal momento che in automatico ASP genererà un nuovo ID, addirittura aggiungendolo al preesistente.
Ovviamente esiste un metodo per risolvere questo problema!!!
Possiamo utilizzare il metodo MioControllo.ClientID che restituisce l'ID che ASP ha assegnato al nostro controllo client side.
Facciamo un esempio!
Supponiamo di aver inserito in una nostra pagina web un controllo asp:TextBox con ID='Testo'. Avremo cioè:
<asp:TextBox ID='Testo' runat="server" />
e di voler generare una funzioncina in javascript che ci permetta di modificare il testo contenuto nella casella. Cioè:
<script language=javascript type="text/javascript">
// Associamo a DocOut l'ID associato al nostro
// controllo dal client
var DocOut="<%=Testo.ClientID%>";
function SettaTesto()
{
var doc=document.getElementById(DocOut);
doc.value='CIAOOOOO!!!!';
}
</script>
Ovviamente dobbiamo richiamare questa funzione collegandola ad esempio alla pressione di un tasto, come:
<input type="button" language="javascript" onclick="SettaImmagine()" />
Il gioco è fatto!!!
Ciao
Ivan
mercoledì 15 marzo 2006
Di seguito vi riporto uno script (client-side) per effettuare la preview di un immagine prima di farne l'upload sul server.
Garantisco che non è stato facile, quindi eccola:
<script language=javascript type="text/javascript">
var maxLarghezza=100;
var maxAltezza=100;
var TipiFile=["bmp","gif","png","jpg","jpeg"];
var Output="img";
var FotoMom;
function ApplicaModifica()
{
var Campo=document.getElementById(Output);
var x=parseInt(FotoMom.width);
var y=parseInt(FotoMom.height);
if (x>maxLarghezza)
{
y*=maxLarghezza/x;
x=maxLarghezza;
}
if (y>maxAltezza)
{
x*=maxAltezza/y;
y=maxAltezza;
}
Campo.style.display=(x<1 || y<1)?"none":"";
Campo.src=FotoMom.src;
Campo.width=x;
Campo.height=y;
}
function SettaImmagine()
{
var source=document.getElementById('file').value;
var ext=source.substring(source.lastIndexOf(".")+1,source.length).toLowerCase();
for (var i=0; i<TipiFile.length; i++) if (TipiFile[i]==ext) break;
if (i<TipiFile.length)
{
xxx='file://localhost/' + source;
xxx=xxx.toLowerCase();
FotoMom=new Image()
FotoMom.src=xxx;
setTimeout("ApplicaModifica()",200);
}
else
{
alert('FORMATO NON VALIDO!!\n');
}
}
</script>
......
......
<BODY>
<br>
<input type="file" id="file" onchange="SettaImmagine()">
<br>
<img id="img" src="">
<br>
</BODY>
Ciao
Ivan
Per collegare più eventi ad un singolo Handler evento in VB.Net basta modificale la clausola degli Handles del metodo aggiungendo i nomi degli eventi che si vogliono associare al metodo stesso.
Separiamo i nomi degli eventi con le virgole come nell'esempio seguente.
Questo codice mostra come collegare al metodo Button_Click gli eventi generati di tre Button differenti.
Sub Button_Click (ByVal sender as System.Object, _
ByVal e as System.EventArgs) _
Handles Button1.Click, Button2.Click, Button3.Click
In questo modo l'evento Button_Click verrà eseguito alla pressione di tutti e tre i pulsanti.
Bisogna fare attenzione a non riabinare poi l'evento On_click di un Button ad un ltro metodo perchè ovviamente l'evento sarebbe associato a due metodi differenti, generando un errore.
Ciao
Ivan
giovedì 9 marzo 2006
Ogni volta che ci troviamo a lavorare con un database e con immagini collegate ad ogni elemento della tabella, nasce il solito dilemma!!!
Come mi comporto con le immagini??
Memorizzo solo la path o l’immagine intera??
La risposta solitamente è:
“MEGLIO SOLO LA PATH!!!”
Un po’ per comodità e soprattutto perché memorizzare le immagini in un db sembra complicato!!
Vi garantisco che non lo è per niente … e spero che non lo sia più nemmeno per voi dopo aver letto questo mio post!!
Innanzitutto dobbiamo creare il DB e la Tabella, allora eccovi gli script per farlo:
‘CREAZIONE DB
CREATE DATABASE [Test] ON PRIMARY
( NAME = N'Test', FILENAME = N'c:\Programmi\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Test.mdf' , SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'Test_log', FILENAME = N'c:\Programmi\Microsoft SQL Server\MSSQL.1\MSSQL\DATA\Test_log.ldf' , SIZE = 7616KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
COLLATE Latin1_General_CI_AS
‘CREAZIONE TABELLA
USE [Test]
GO
CREATE TABLE [dbo].[Album](
[IdFoto] [int] IDENTITY(1,1) NOT NULL,
[Foto] [image] NULL,
CONSTRAINT [PK_Album] PRIMARY KEY CLUSTERED
(
[IdFoto] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Per chi fosse meno esperto di SQL Server 2005:
- aprire SQL Server Management;
- cliccare su “New Query …” basta copiare ed incollare lo script per la creazione del DB ed eseguire la query;
- cliccare su “New Query … ” copiare ed incollare lo script per la creazione della tabella ed eseguire la query.
Ora il DB Test e la sua cartella Album dovrebbero essere stati creati.
Passiamo all’implementazione del codice. Sviluppiamo un piccolo programmino per la memorizzazione e la visualizzazione delle immagini nel DB appena creato.
Apriamo VSTO 2005 e iniziamo un nuovo progetto.
Nel primo form inseriamo una Toolstrip e su di essa inseriamo due pulsanti. Inseriamo poi una Label nella parte del form che rimane libera e dovremmo ottenere una cosa del genere:

Passando al codice inseriamo questo che segue:
Imports System
Imports Microsoft.VisualBasic
Public Class Form3
Dim testo As String = "Demo di DB Image con SQL " _
& "Server 2005 in VB.Net"
Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
If Label1.Text.Length <> 0 Then
Label1.Text = Microsoft.VisualBasic.Right(Label1.Text, _
Label1.Text.Length - 1)
Else
Label1.Text = testo
End If
End Sub
Private Sub ToolStripButton1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ToolStripButton1.Click
Dim frmCarica As New Caricamento
frmCarica.ShowDialog()
End Sub
Private Sub ToolStripButton2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ToolStripButton2.Click
Dim frmVedi As New Visualizza
frmVedi.ShowDialog()
End Sub
End Class
Inseriamo ora un nuovo Form che chiameremo Caricamento. In questo inseriamo una PictureBox, una TextBox, una OpenFileDialog e due Button. Lavorando un po’ con il designer potreste ottenere questo:

Il codice da aggiungere a questo form è:
Imports System
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Public Class Caricamento
Dim Archivio As SqlConnection
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Archivio = New SqlConnection
Archivio.ConnectionString = "Data Source=(local)\SQLEXPRESS;" _
& "Database=Test;Integrated Security=SSPI;"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
OpenFileDialog1.Filter = "BMP - Bitmap Windows | *.bmp | " _
& "GIF - CompuServe Graphics Interchange | *.gif | JPG - " _
& "Compatibile JFIF | *.jpg"
OpenFileDialog1.Title = "Seleziona l'immagine da caricare ..."
OpenFileDialog1.ShowDialog()
If OpenFileDialog1.FileName <> "" Then
TextBox1.Text = OpenFileDialog1.FileName.ToString
PictureBox1.Image = Image.FromFile _
(OpenFileDialog1.FileName.ToString)
End If
End Sub
Private Function ImageToStream() As Byte()
Dim Image As New Bitmap(TextBox1.Text)
Dim stream As MemoryStream = New MemoryStream()
Image.Save(stream, _
System.Drawing.Imaging.ImageFormat.Bmp)
Return stream.ToArray()
End Function
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
If File.Exists(TextBox1.Text) Then
Dim Query As String
Query = "INSERT INTO Album (Foto) VALUES (@Img)"
Dim comando As New SqlCommand(Query, Archivio)
Archivio.Open()
Dim param As SqlParameter = _
New SqlParameter("@Img", SqlDbType.Binary)
param.Value = ImageToStream()
comando.Parameters.Add(param)
comando.ExecuteNonQuery()
comando = Nothing
Archivio.Close()
PictureBox1.Image = Nothing
TextBox1.Text = ""
Else
MessageBox.Show("File inesistente!!", "Test DB Image", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation, _
MessageBoxDefaultButton.Button1, _
MessageBoxOptions.DefaultDesktopOnly)
End If
End Sub
End Class
Inseriamo ancora un altro Form che chiameremo Visualizza. Inseriamo una Toolstrip con due pulsanti ed una PictureBox per ottenere questo.

Con questo codice:
Imports System
Imports System.IO
Imports System.Data
Imports System.Data.SqlClient
Public Class Visualizza
Dim conta As Integer = 1
Dim Album As New Collection
Dim Query As String
Dim Archivio As SqlConnection
Private Sub Form2_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Archivio = New SqlConnection
Archivio.ConnectionString = "Data Source=(local)\SQLEXPRESS;" _
& "Database=Test;Integrated Security=SSPI;"
Query = "SELECT Foto FROM ALBUM"
Dim cmd As New SqlCommand(Query, Archivio)
Archivio.Open()
Dim I As Integer = 0
Dim reader As SqlDataReader = cmd.ExecuteReader()
Dim Temp As Byte()
While reader.Read
Temp = reader(0)
Album.Add(Temp)
End While
If Album.Count > 0 Then
Temp = CType(Album.Item(conta), Byte())
Dim Img As MemoryStream = New MemoryStream(Temp)
PictureBox1.Image = Image.FromStream(Img)
End If
End Sub
Private Sub ToolStripButton2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ToolStripButton2.Click
Dim Temp As Byte()
If conta > 1 Then
conta = conta - 1
Temp = CType(Album.Item(conta), Byte())
Dim Img As MemoryStream = New MemoryStream(Temp)
PictureBox1.Image = Image.FromStream(Img)
End If
End Sub
Private Sub ToolStripButton1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ToolStripButton1.Click
Dim Temp As Byte()
If conta < Album.Count Then
conta = conta + 1
Temp = CType(Album.Item(conta), Byte())
Dim Img As MemoryStream = New MemoryStream(Temp)
PictureBox1.Image = Image.FromStream(Img)
End If
End Sub
End Class
A questo punto siamo pronti per testare l’applicazione.
Il risultato dovrebbe essere abbastanza soddisfacente. Infatti se dal form iniziale inseriamo prima un immagine e poi passiamo a visualizzarla dovremmo avere una cosa del genere.

Confido che almeno i soggetti della foto siano diversi! ;)
… sono miei e GUAI A CHI ME LI TOCCA!!
Spero di avervi chiarito un po’ le idee.
Ciao
Ivan
?>
martedì 7 marzo 2006
Sto scoprendo sempre più la forza delle API!!
Riporto il codice che attraverso la shell32.dll mi permette di richiamare la finestra di shutdown del sistema. ... A me è stata utile!!
Public Class Form1
Declare Sub ShutDownDialog Lib "shell32.dll" Alias "#60" (ByVal hwndOwner As Long)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Try
ShutDownDialog(Me.Handle)
Exit Try
Catch Ex As Exception
'ERRORE
End Try
End Sub
End Class
Basta aprire un form ed inserirci un pulsante.
Ciao
Ivan
sabato 4 marzo 2006
Può accadere che si abbia la necessità di disabilitare la pressione del pulsante "Start"!
In che caso?? .... Bella domanda!!
Mbhe! Forse accade solo a me!! ... comunque ognuno può usarla quando e come meglio crede.
Apriamo un nuovo form con una Label ed un semplice Button ed inseriamo il seguente codice:
Private Declare Function FindWindowEx Lib "user32" _
Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, _
ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer
Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As Integer, _
ByVal fEnable As Integer) As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Label1.Text = "Enabled"
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim bEnable As Boolean
If Label1.Text = "Enabled" Then
Label1.Text = "Disabled"
bEnable = False
Else
Label1.Text = "Enabled"
bEnable = True
End If
Dim lHwnd As Integer
lHwnd = FindWindowEx(0&, 0&, "Shell_TrayWnd", vbNullString)
lHwnd = FindWindowEx(lHwnd, 0&, "Button", vbNullString)
Call EnableWindow(lHwnd, bEnable)
End Sub
Ovviamente, come dice il mio amico Brunetti, il linguaggio non ha importanza siamo in .NET!!
Ciao
Ivan