Lo scopo di questo breve post è dare un veloce sguardo alla prima cosa che notiamo nell’SDK, ovvero il Simulator, per capire come possiamo creare applicazioni per Surface senza avere a disposizione il dispositivo.
In questo momento non dispongo di una macchina adeguata, quindi ovviamente, non sono in grado di valutare correttamente le performance. Ricordo che il Simulator funziona con una risoluzione minima di 1280×960.
Per scrivere subito un pò di codice, ho scimmiottato quanto descritto in questo video, e ho lanciato il simultatore prima di andare con il debug. Se il simulatore non è in esecuzione al momento dell’avvio del debug, l’applicazione parte come WPF application, e quindi con funzionalità ridotte rispetto a quelle attese. Al momento non ho ancora capito se e come agganciare il debug direttamente al simulatore, quindi per ora mi assicuro di averlo in esecuzione prima del debug.
Il risultato è visibile nella foto di seguito, con le poche righe di codice che vedrete nel video.


Rispetto all’esempio del video ho aggiunto solo un bottone per uscire dall’applicazione.
Purtroppo, nel printscreen non viene visualizzato il bordo della finestra del simulator, e neanche i mouse usati (3 contemporaneamente, di cui uno PS-2 e due USB), visualizzati con un cursore stilizzato a forma di “dito”. Infatti ogni mouse simula un “punto di contatto” che potremmo avere nell’esecuzione dell’applicazione.
Nell’immagine vengono comunque visualizzati due cerchietti che sono poi i punti di contatto usati durante l’esecuzione.
Surface consente fino a 52 punti di contatto contemporanei (non mi chiedete l’origine di questo limite, me lo chiedo anche io).
L’applicazione in sé non è niente di speciale, ma se pensate alle poche righe necessarie per implementarlo, si può facilmente capire che l’SDK anche allo stato attuale, fornisce un bel pò di classi pronte all’uso. In futuro probabilmente verranno aggiunte altre classi per facilitare ulteriormente lo sviluppo.
-
Ente Certificatore : Microsoft
-
Nome Esame : 070-529 Microsoft .NET Framework 2.0 – Distributed Application Development
-
Costo : 140€
-
Modalità esame : presso un centro Prometric, 40 domande, 125 minuti, domande a risposta singola e multipla
-
Score minimo : 700 su 1000, ogni domanda ha un peso diverso
-
Certificazione conseguita : si (795/1000) -
Microsoft Certified Technology Specialist – .NET Framework 2.0 Distributed Applications Development
-
Livello di difficoltà (1-5) : 4.5
-
Utilità tecnica (1-5) : 3.5
-
Preparazione : 2 mesi circa
-
Ente Certificatore : Microsoft
-
Nome Esame : 070-528 Microsoft .NET Framework 2.0 – Web-Based Client Development
-
Costo : 140€
-
Modalità esame : presso un centro Prometric, 45 domande, 150 minuti, domande a risposta singola e multipla, possono esserci anche domande che richiedono drag&drop
-
Score minimo : 700 su 1000, ogni domanda ha un peso diverso
-
Certificazione conseguita : si (841/1000) -
Microsoft Certified Technology Specialist – .NET Framework 2.0 Web Applications
-
Livello di difficoltà (1-5) : 4
-
Utilità tecnica (1-5) :4
-
Preparazione : da 1 a 2 mesi
-
Ente Certificatore : Microsoft
-
Nome Esame : 070-526 Microsoft .NET Framework 2.0 – Windows-Based Client Development
-
Costo : 140€
-
Modalità esame : presso un centro Prometric, 41 domande, 125 minuti, domande a risposta singola e multipla, possono esserci anche domande che richiedono drag&drop
-
Score minimo : 700 su 1000, ogni domanda ha un peso diverso
-
Certificazione conseguita : si (840/1000) -
Microsoft Certified Technology Specialist – .NET Framework 2.0 Windows Applications
-
Livello di difficoltà (1-5) : 4
-
Utilità tecnica (1-5) :4
-
Preparazione : da 1 a 2 mesi
Un metodo rapido e veloce per esportare un semplice file Excel in un file CSV:
using _Excel = Microsoft.Office.Interop.Excel;
…
[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
…
/// <summary>
///
/// </summary>
/// <param name=”sInFile”>Il file .xls in input</param>
/// <param name=”sOutFile”>Il file .csv in output</param>
/// <remarks>
/// Le seguenti considerazioni sono relative a questo specifico esempio.
/// Il file .xls deve essere in formato 97/2003, no 2007.
/// Il file .csv non è “comma-separated”, ma è “semicolon-separated”, cioè vengono separati i valori con “;”
/// I filename devono essere in “absolute path” e non in “relative path”.
/// </remarks>
/// <returns>Ritorna true se l’esportazione riesce con successo, false altrimenti.</returns>
private bool ExportXlsToCsv(string sInFile, string sOutFile)
{
bool Result = File.Exists(sInFile); // verifica che il file .xls esista
if (Result)
{
_Excel.ApplicationClass excel = null; // l’istanza di Excel
int excelProcessId = 0; //id del processo creato per l’istanza
try
{
if (File.Exists(sOutFile)) // se il file di destinazione esiste…
{
File.Delete(sOutFile); // … lo elimina preventivamente
}
excel = new _Excel.ApplicationClass(); // istanzia Excel
GetWindowThreadProcessId(excel.Hwnd, out excelProcessId); // ricava l’id assegnato per il processo generato
excel.Visible = false; // evita che l’istanza dell’applicativo sia visibile all’utente
_Excel.Workbook workBook = excel.Workbooks.Open(sInFile, 0, true, 5, “”, “”, true, _Excel.XlPlatform.xlWindows, “\t”, false, false, 0, true, 1, 0); // apre il file .xls
workBook.SaveAs(sOutFile, _Excel.XlFileFormat.xlCSVMSDOS, Type.Missing, Type.Missing, Type.Missing, Type.Missing, _Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // salva il file in formato .csv
excel.DisplayAlerts = false; // evita che venga richiesta la conferma di salvataggio alla chiusura di Excel (dato che è già salvato in .csv)
excel.Quit(); // chiude l’istanza di Excel
Result = true;
}
catch
{
Result = false;
}
finally
{
excel = null; // una volta chiusa l’istanza, questa assegnazione è comunque necessaria
if (excelProcessId != 0)
{
// se per qualche motivo non viene chiusa l’istanza Excel, facciamo una kill
int iMaxTimeoutMs = 3000; // i ms di attesa per aspettare che l’istanza venga chiusa correttamente
int iCheck = 250; // i ms per ogni controllo
while ( (iMaxTimeoutMs>0) && (Process.GetProcessById(excelProcessId) != null) )
{
Thread.Sleep(iCheck);
iMaxTimeoutMs -= iCheck;
}
Process excelProcess = Process.GetProcessById(excelProcessId);
if (excelProcess != null) // se ancora a questo punto l’istanza è attiva…
{
// (non dovrebbe servire, ma non si sa mai)
excelProcess.Kill(); // …la si butta giù di forza !
}
}
}
}
return Result;
}
-
Ente Certificatore : Microsoft
-
Nome Esame : 070-536 Microsoft .NET Framework 2.0 – Application Development Foundation
-
Costo : 140€
-
Modalità esame : presso un centro Prometric, 40 domande, 2h15′, domande a risposta singola e multipla, possono esserci anche domande che richiedono drag&drop
-
Score minimo : 700 su 1000, ogni domanda ha un peso diverso
-
Certificazione conseguita : si (858/1000)
-
Livello di difficoltà (1-5) : 4
-
Utilità tecnica (1-5) :4
-
Annotazioni : è l’esame di base per ogni tipologia di certificazione MCTS per .NET; questo vuol dire che da solo non costituisce certificazione specifica MCTS.
-
Preparazione : da 2 a 4 mesi
MCP me too!
7/04/2008
Da oggi sono anche io un “MCP”.
Ho superato con 858/1000 l’esame 70-536 di Microsoft (TS Microsoft .NET 2.0 – Application Development Foundation).
Sono molto contento, mi sento bene ora. Nell’ultima settimana ero diventato come una trottola, ed ero estremamente nervoso.
Devo dire comunque che nonostante il buon punteggio (in cui non onestamente non speravo), l’esame è stato veramente stressante, e le due ore e un quarto (mi pare…) sono passate in un lampo per rispondere a 40 domande, alcune onestamente abbastanza difficili…
Ora mi aspetta il 70-526 per prendere la prima certificazione (formata appunto da due esami).
Ma di questo ne parleremo in un altro post (spero).
Multicast Delegate con C#
6/04/2008
Nella mia infinita, consapevole ignoranza, ho scoperto l’esistenza dei Multicast Delegate.
In pratica si traduce nella possibilità di sommare o sottrarre l’esecuzione di diversi metodi che siano conformi ad uno stesso delegate.
Questo comporta un’esecuzione in serie, secondo la somma (o la sottrazione) effettuata.
Mi spiego meglio con un esempio (liberamente tratto da questo esempio msdn):
namespace ConsoleApplication1
{
delegate int delegate1(string s);
class Class1
{
public static int Hello(string s)
{
Console.Write(“hello {0} “,s);
return s.Length;
}
public static int World(string s)
{
Console.Write(” world {0} “, s);
return s.Length;
}
public static int CarriageReturn(string s)
{
Console.WriteLine(” {0} “, s);
return s.Length;
}
public Class1()
{
delegate1 d1, d2, d3, d4;
d1 = Hello;
d2 = World;
d3 = CarriageReturn;
d4 = d1 + d2 + d3;
d4(“!”);
Console.ReadLine();
}
}
}
Questo comporta il seguente output :
hello ! world ! !
Quindi abbiamo eseguito i metodi nella sequenza identificata dalla somma. Come dicevo, si possono eseguire anche operazioni di sottrazione, corrispondenti alla fine ad una eliminazione dalla sequenza di esecuzione.
Quindi avremmo potuto scrivere (al posto della riga in rosso)
d4(“!”);
d4 -= d2;
d4(“!”);
e ottenere :
hello ! world ! !
hello ! !
Questo “sommatoria” si può eseguire come dicevo, solo se i metodi usati come addendi sono conformi ad uno stesso delegate. Lo stesso discorso non vale per un eventuale valore di
ritorno del metodo, che non corrisponde ad una “sommatoria dei valori di ritorno” dei metodi addendi.
In pratica se avessi scritto :
int i1 = d4(“!”);
Console.WriteLine(“Return : {0}”, i1);
d4 -= d2;
int i2 = d4(“!”);
Console.WriteLine(“Return : {0}”, i2);
avrei ottenuto come output :
hello ! world ! !
Return : 1
hello ! !
Return : 1
quindi è chiaro che il risultato è relativo solo all’ultimo metodo eseguito.
Questo si evidenzia ancora maggiormente se lanciamo un ILDASM sull’assembly, dove notiamo che i punti in cui eseguiamo il delegate d4, viene composto dalle chiamate in sequenza dei metodi che in quel momento lo compongono.
Il risultato di una sommatoria anche del valore di ritorno, si potrebbe comunque ottenere, se proprio necessario in uno scenario del genere, ricorrendo semplicemente (ad esempio) a delle variabili statiche con visibilità globale per la classe.
Immagino sia un baco…
Scenario : Windows Server 2008 Enterprise
Azione : Creare uno share di rete ad una utenza specifica, che ancora non esiste
Prerequisito : Loggato con una utenza del gruppo Administrators
Esecuzione :
1. Creazione Utenza
- Start > Administrative Tools > Server Manager
- dal Server Manager > Configuration > Local Users and Groups > Users
- dal pannello Users > tasto destro > New User…
- inserisco i dati :
- User Name : Prova
- Full Name : Utente di Prova
- Description : Descrizione Utente di Prova
- Password : pippobaudo.2008
- tolgo il check a “User must change password at next logon”
- premo il tasto “Create” e l’utente viene generato
- di default l’utente appena creato appartiene al solo gruppo “Users”
- chiudo la finestra aperta di creazione utente e la finestra di Server Manager
2. Attivazione Share
- vado in “Computer” (le risorse del computer) > disco “C” > tasto destro > New > Folder > creo una nuova cartella “Prova”
- una volta creata la cartella “Prova”, faccio tasto destro su di essa e dal menù scelgo “Share…”
- si apre la cartella di File Sharing, in cui mi viene di default visualizzato l’utente Administrator come Owner
- dalla combobox di utenze premo la freccia giù, e mi vengono elencate le utenze registrate
- scelgo l’utenza “Utente di Prova” e premo il tasto “Add”
- ECCO L’ERRORE : mi viene visualizzata una dialog di errore in cui il messaggio è “Unable to locate user Utente di Prova”
Soluzione :
- Ritornare nella finestra del Server Manager (Start > Administrative Tools > Server Manager)
- dal Server Manager > Configuration > Local Users and Groups > Users
- tasto destro sull’utenza “Prova” > Properties
- cancellare il contenuto del textbox “Full Name” (che contiene “Utente di Prova”) lasciando il campo vuoto, e quindi fare “OK”
- a questo punto torno in “Computer” > disco “C” > tasto destro su “Prova”
- si apre la cartella di File Sharing, e dalla combobox di utenze premo la freccia giù, e mi vengono elencate le utenze registrate
- scelgo l’utenza che a questo punto si chiama “Prova” e premo il tasto “Add”
- ORA L’UTENTE VIENE AGGIUNTO
- posso anche scegliere il tipo di utenza nella voce Permission Level, tra Reader, Contributor o Co-Owner
- premo il tasto “Share”
- mi viene visualizzata la finestra “Network discovery and file sharing”, in cui devo scegliere la voce “Yes, turn on network discovery…” e a questo punto è tutto a posto.
Chi ne sa qualcosa in più è invitato ad aggiungere un commento in merito.
Scenario : Sql Server 2005 con un database appena creato tramite uno script
Problema : Non si riescono a creare Database Diagrams, in quanto il supporto per la funzionalità stessa non è presente e ad ogni tentativo viene visualizzata una dialog di errore con scritto il messaggio : “Database diagram support objects cannot be installed because this database does not have a valid owner. To continue, first use the Files page of the Database Properties dialog box or the ALTER AUTHORIZATION statement to set the database owner to a valid login, then add the database diagram support objects.”. Andando nelle proprietà del database, seguendo le indicazioni del messaggio non sembra risolversi il problema.
Soluzione : Eseguire il seguente script :
use [master] EXEC sp_dbcmptlevel 'yourDB', '90'; go ALTER AUTHORIZATION ON DATABASE::yourDB TO "yourLogin" go use [yourDB] go EXECUTE AS USER = N'dbo' REVERT go
