<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Felice Pollano Blog - Recipes</title>
    <link>http://www.felicepollano.com/</link>
    <description>The official Fatica Labs Blog!</description>
    <language>en-us</language>
    <copyright>Felice Pollano</copyright>
    <lastBuildDate>Wed, 16 Jun 2010 15:52:39 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>felice@felicepollano.com</managingEditor>
    <webMaster>felice@felicepollano.com</webMaster>
    <item>
      <trackback:ping>http://www.felicepollano.com/Trackback.aspx?guid=982dfdf2-cec1-462b-b160-0f8876ce7958</trackback:ping>
      <pingback:server>http://www.felicepollano.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.felicepollano.com/PermaLink,guid,982dfdf2-cec1-462b-b160-0f8876ce7958.aspx</pingback:target>
      <dc:creator>Felice Pollano</dc:creator>
      <wfw:comment>http://www.felicepollano.com/CommentView,guid,982dfdf2-cec1-462b-b160-0f8876ce7958.aspx</wfw:comment>
      <wfw:commentRss>http://www.felicepollano.com/SyndicationService.asmx/GetEntryCommentsRss?guid=982dfdf2-cec1-462b-b160-0f8876ce7958</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="justify">
Probabilmente vi sarà capitato di dovere eseguire qualche azione all’interno del vostro
software dipendentemente da trigger innescati da data e/o ora. Per esempio un certo
processo non si scatena del week-end, oppure un altro processo deve partire solo a
mezzanotte etc etc. Quando queste cose non siano attuabili esternamente con il task
scheduler di sistema, sarebbe bello poter avere una libreria pronto uso in .NET. Ebbene
questa libreria c’è, ed è il parser di <a href="http://en.wikipedia.org/wiki/CRON_expression" target="_blank">espressioni
Cron</a> che <a href="https://sourceforge.net/projects/cronnet/files/" target="_blank">trovate
qui</a>. Lungi dall’essere un concetto moderno, si tratta di un modo di esprimere
range temporali tramite una stringa che arriva da Unix. Oggi chiamiamo una cosa simile
“Domain Specific Language”, ma tant’è il concetto è il medesimo. Lungi anche dall’
essere originale il concetto in .NET, la <a href="https://sourceforge.net/projects/cronnet/" target="_blank">libreria
che propongo</a> è una estrapolazione di codice dalla più completa e complessa libreria <a href="http://quartznet.sourceforge.net/" target="_blank">Quartz.NET</a>,
a sua volta un porting della libreria Java <a href="http://www.quartz-scheduler.org/" target="_blank">Quartz</a>.
Se non volete introdurre troppa complessità al vostro deploy aggiungendo una nuova
libreria, potete “grabbare” le classi dalla dll di Cron.NET ( sono tre file… ) e compilarli
con il vostro progetto, ed avrete a disposizione tutta la potenza delle espressioni
Cron ;).
</p>
        <p align="justify">
Già, ma come funzionano le espressioni Cron ? Facciamo un paio di esempi:
</p>
        <p align="justify">
          <strong>"* * 10-11 L * ?" = </strong>questo trigger è valido l’ultimo del mese dalle
10-11
</p>
        <p align="justify">
          <strong>"* * * ? * MON-FRI" = </strong>questo trigger è valido tutti i giorni, a tutte
le ore, eccetto il week end.
</p>
        <p align="justify">
Ok, questo da l’idea delle potezialità della cosa, ma ovviamente serivirebbe una più
estesa…
</p>
        <h4>Documentazione
</h4>
        <p>
Una espressione Cron è composta da <strong>6 campi obbligatori</strong>, più <strong>uno
opzionale</strong>. Il significato dei campi è schematizzato nella tabella qui sotto:
</p>
        <table cellspacing="8">
          <tbody>
            <tr>
              <th align="left">
Campo</th>
              <th align="left">
 </th>
              <th align="left">
Valori permessi</th>
              <th align="left">
 </th>
              <th align="left">
Caratteri speciali ammessi</th>
            </tr>
            <tr>
              <td align="left">
Secondi</td>
              <td align="left">
 </td>
              <td align="left">
0-59</td>
              <td align="left">
 </td>
              <td align="left">
, - /</td>
            </tr>
            <tr>
              <td align="left">
Minuti</td>
              <td align="left">
 </td>
              <td align="left">
0-59</td>
              <td align="left">
 </td>
              <td align="left">
, - /</td>
            </tr>
            <tr>
              <td align="left">
Ore</td>
              <td align="left">
 </td>
              <td align="left">
0-23</td>
              <td align="left">
 </td>
              <td align="left">
, - /</td>
            </tr>
            <tr>
              <td align="left">
Giorno del mese</td>
              <td align="left">
 </td>
              <td align="left">
1-31</td>
              <td align="left">
 </td>
              <td align="left">
, - ? / L W C</td>
            </tr>
            <tr>
              <td align="left">
Mese</td>
              <td align="left">
 </td>
              <td align="left">
1-12 or JAN-DEC</td>
              <td align="left">
 </td>
              <td align="left">
, - /</td>
            </tr>
            <tr>
              <td align="left">
Giorno della settimana</td>
              <td align="left">
 </td>
              <td align="left">
1-7 or SUN-SAT</td>
              <td align="left">
 </td>
              <td align="left">
, - ? / L #</td>
            </tr>
            <tr>
              <td align="left">
Anno ( Opzionale )</td>
              <td align="left">
 </td>
              <td align="left">
vuoto, 1970-2099</td>
              <td align="left">
 </td>
              <td align="left">
, - /</td>
            </tr>
          </tbody>
        </table>
        <p>
 
</p>
        <p align="justify">
Il carattere jolly <strong>‘*’</strong> può sempre essere usato con il significato
di “tutti i valori”, per esempio se metto <strong>‘*’</strong> nel campo minuti significa
tutti i minuti.
</p>
        <p align="justify">
Il carattere<strong> ‘?’</strong> può essere usato solo come Giorno del mese o giorno
della settimana. Significa “nessun valore in particolare” e serve quando devo fissare
l’altro. Se per esempio fisso il giorno della settimana metterò<strong> ‘?’</strong> nel
giorno del mese, e viceversa.
</p>
        <p align="justify">
Il carattere<strong> ‘-‘</strong> lo utilizzo quando voglio specificare un range:
per esempio 10-12 nel campo ora significa dalle 10 a tutte le 12.
</p>
        <p align="justify">
Uso invece la <strong>‘,’</strong> quando voglio specificare singolarmente più valori
possibili: JAN,MAR significa il mese di Gennaio e di Marzo, ma non Febbraio ( e, ovviamente,
non tutti gli altri ).
</p>
        <p align="justify">
Per specificare dei periodi utilizzo<strong> ‘/’</strong>: per esempio se metto 0/15
nel campo secondi, significa “ogni 15 secondi”: sarà attivo il trigger quindi ai secondi
15,30,45 etc etc.
</p>
        <p align="justify">
Il carattere speciale<strong> ‘L’</strong> significa ultimo. Nel campo mese significa
semplicemente l’ultimo giorno del mese (30/31/28 o 29 ) in modo concorde con il mese
/ anno bisestile. Nel campo settimana significa semplicemente 7 ( cioè Sabato ), ma
se <strong>preceduto da un numero</strong> significa “l’ultimo xxxx del mese”. Per
esempio se scrivo <strong>6L</strong> significa <strong>l’ultimo Venerdì del mese</strong>. 
</p>
        <p align="justify">
Il carettere ‘W’ può essere specificato solo nel campo giorno del mese, preceduto
da un solo carattere, e significa “il giorno lavorativo più vicino a”. Per esempio
se scrivo <strong>1W</strong> significa <strong>il giorno lavorativo più vicino al
primo del mese</strong>. Se scrivo <strong>LW</strong> significa <strong>l’ultimo
giorno lavorativo del mese</strong>.
</p>
        <p align="justify">
Per ultimo il carattere ‘#’, utilizzabile solo nel giorno della settimana, indica
l’ennesimo xxxx del mese. Per esempio, se mi interessa il <strong>terzo venerdì del
mese</strong>, scriverò <strong>6#3</strong>.
</p>
        <p>
Per utilizzare una cron expression basta creare un istanza dell’ogegtto CronExpression,
passando la stringa sul costruttore. Ecco un esempio:
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span> [Test]</pre>
          <pre>
            <span class="lnum"> 2: </span>
            <span class="kwrd">public</span>
            <span class="kwrd">void</span> LastOfTheMonth()</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> {</pre>
          <pre>
            <span class="lnum"> 4: </span> var
exp = <span class="kwrd">new</span> CronExpression(<span class="str">"* * * L * ?"</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> Assert.IsTrue(exp.IsSatisfiedBy(<span class="kwrd">new</span> DateTime(2000,
1, 31)));</pre>
          <pre>
            <span class="lnum"> 6: </span> Assert.IsTrue(exp.IsSatisfiedBy(<span class="kwrd">new</span> DateTime(2000,
2, 29)));</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> Assert.IsFalse(exp.IsSatisfiedBy(<span class="kwrd">new</span> DateTime(2000,
2, 28)));</pre>
          <pre>
            <span class="lnum"> 8: </span> }</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=982dfdf2-cec1-462b-b160-0f8876ce7958" />
      </body>
      <title>Cron.NET: un DSL per il tempo…</title>
      <guid isPermaLink="false">http://www.felicepollano.com/PermaLink,guid,982dfdf2-cec1-462b-b160-0f8876ce7958.aspx</guid>
      <link>http://www.felicepollano.com/2010/06/16/CronNETUnDSLPerIlTempo.aspx</link>
      <pubDate>Wed, 16 Jun 2010 15:52:39 GMT</pubDate>
      <description>&lt;p align="justify"&gt;
Probabilmente vi sarà capitato di dovere eseguire qualche azione all’interno del vostro
software dipendentemente da trigger innescati da data e/o ora. Per esempio un certo
processo non si scatena del week-end, oppure un altro processo deve partire solo a
mezzanotte etc etc. Quando queste cose non siano attuabili esternamente con il task
scheduler di sistema, sarebbe bello poter avere una libreria pronto uso in .NET. Ebbene
questa libreria c’è, ed è il parser di &lt;a href="http://en.wikipedia.org/wiki/CRON_expression" target="_blank"&gt;espressioni
Cron&lt;/a&gt; che &lt;a href="https://sourceforge.net/projects/cronnet/files/" target="_blank"&gt;trovate
qui&lt;/a&gt;. Lungi dall’essere un concetto moderno, si tratta di un modo di esprimere
range temporali tramite una stringa che arriva da Unix. Oggi chiamiamo una cosa simile
“Domain Specific Language”, ma tant’è il concetto è il medesimo. Lungi anche dall’
essere originale il concetto in .NET, la &lt;a href="https://sourceforge.net/projects/cronnet/" target="_blank"&gt;libreria
che propongo&lt;/a&gt; è una estrapolazione di codice dalla più completa e complessa libreria &lt;a href="http://quartznet.sourceforge.net/" target="_blank"&gt;Quartz.NET&lt;/a&gt;,
a sua volta un porting della libreria Java &lt;a href="http://www.quartz-scheduler.org/" target="_blank"&gt;Quartz&lt;/a&gt;.
Se non volete introdurre troppa complessità al vostro deploy aggiungendo una nuova
libreria, potete “grabbare” le classi dalla dll di Cron.NET ( sono tre file… ) e compilarli
con il vostro progetto, ed avrete a disposizione tutta la potenza delle espressioni
Cron ;).
&lt;/p&gt;
&lt;p align="justify"&gt;
Già, ma come funzionano le espressioni Cron ? Facciamo un paio di esempi:
&lt;/p&gt;
&lt;p align="justify"&gt;
&lt;strong&gt;"* * 10-11 L * ?" = &lt;/strong&gt;questo trigger è valido l’ultimo del mese dalle
10-11
&lt;/p&gt;
&lt;p align="justify"&gt;
&lt;strong&gt;"* * * ? * MON-FRI" = &lt;/strong&gt;questo trigger è valido tutti i giorni, a tutte
le ore, eccetto il week end.
&lt;/p&gt;
&lt;p align="justify"&gt;
Ok, questo da l’idea delle potezialità della cosa, ma ovviamente serivirebbe una più
estesa…
&lt;/p&gt;
&lt;h4&gt;Documentazione
&lt;/h4&gt;
&lt;p&gt;
Una espressione Cron è composta da &lt;strong&gt;6 campi obbligatori&lt;/strong&gt;, più &lt;strong&gt;uno
opzionale&lt;/strong&gt;. Il significato dei campi è schematizzato nella tabella qui sotto:
&lt;/p&gt;
&lt;table cellspacing="8"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th align="left"&gt;
Campo&lt;/th&gt;
&lt;th align="left"&gt;
&amp;nbsp;&lt;/th&gt;
&lt;th align="left"&gt;
Valori permessi&lt;/th&gt;
&lt;th align="left"&gt;
&amp;nbsp;&lt;/th&gt;
&lt;th align="left"&gt;
Caratteri speciali ammessi&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Secondi&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
0-59&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Minuti&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
0-59&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Ore&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
0-23&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Giorno del mese&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
1-31&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - ? / L W C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Mese&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
1-12 or JAN-DEC&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Giorno della settimana&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
1-7 or SUN-SAT&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - ? / L #&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;
Anno ( Opzionale )&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
vuoto, 1970-2099&lt;/td&gt;
&lt;td align="left"&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td align="left"&gt;
, - /&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p align="justify"&gt;
Il carattere jolly &lt;strong&gt;‘*’&lt;/strong&gt; può sempre essere usato con il significato
di “tutti i valori”, per esempio se metto &lt;strong&gt;‘*’&lt;/strong&gt; nel campo minuti significa
tutti i minuti.
&lt;/p&gt;
&lt;p align="justify"&gt;
Il carattere&lt;strong&gt; ‘?’&lt;/strong&gt; può essere usato solo come Giorno del mese o giorno
della settimana. Significa “nessun valore in particolare” e serve quando devo fissare
l’altro. Se per esempio fisso il giorno della settimana metterò&lt;strong&gt; ‘?’&lt;/strong&gt; nel
giorno del mese, e viceversa.
&lt;/p&gt;
&lt;p align="justify"&gt;
Il carattere&lt;strong&gt; ‘-‘&lt;/strong&gt; lo utilizzo quando voglio specificare un range:
per esempio 10-12 nel campo ora significa dalle 10 a tutte le 12.
&lt;/p&gt;
&lt;p align="justify"&gt;
Uso invece la &lt;strong&gt;‘,’&lt;/strong&gt; quando voglio specificare singolarmente più valori
possibili: JAN,MAR significa il mese di Gennaio e di Marzo, ma non Febbraio ( e, ovviamente,
non tutti gli altri ).
&lt;/p&gt;
&lt;p align="justify"&gt;
Per specificare dei periodi utilizzo&lt;strong&gt; ‘/’&lt;/strong&gt;: per esempio se metto 0/15
nel campo secondi, significa “ogni 15 secondi”: sarà attivo il trigger quindi ai secondi
15,30,45 etc etc.
&lt;/p&gt;
&lt;p align="justify"&gt;
Il carattere speciale&lt;strong&gt; ‘L’&lt;/strong&gt; significa ultimo. Nel campo mese significa
semplicemente l’ultimo giorno del mese (30/31/28 o 29 ) in modo concorde con il mese
/ anno bisestile. Nel campo settimana significa semplicemente 7 ( cioè Sabato ), ma
se &lt;strong&gt;preceduto da un numero&lt;/strong&gt; significa “l’ultimo xxxx del mese”. Per
esempio se scrivo &lt;strong&gt;6L&lt;/strong&gt; significa &lt;strong&gt;l’ultimo Venerdì del mese&lt;/strong&gt;. 
&lt;/p&gt;
&lt;p align="justify"&gt;
Il carettere ‘W’ può essere specificato solo nel campo giorno del mese, preceduto
da un solo carattere, e significa “il giorno lavorativo più vicino a”. Per esempio
se scrivo &lt;strong&gt;1W&lt;/strong&gt; significa &lt;strong&gt;il giorno lavorativo più vicino al
primo del mese&lt;/strong&gt;. Se scrivo &lt;strong&gt;LW&lt;/strong&gt; significa &lt;strong&gt;l’ultimo
giorno lavorativo del mese&lt;/strong&gt;.
&lt;/p&gt;
&lt;p align="justify"&gt;
Per ultimo il carattere ‘#’, utilizzabile solo nel giorno della settimana, indica
l’ennesimo xxxx del mese. Per esempio, se mi interessa il &lt;strong&gt;terzo venerdì del
mese&lt;/strong&gt;, scriverò &lt;strong&gt;6#3&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
Per utilizzare una cron expression basta creare un istanza dell’ogegtto CronExpression,
passando la stringa sul costruttore. Ecco un esempio:
&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt; [Test]&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; LastOfTheMonth()&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; var
exp = &lt;span class="kwrd"&gt;new&lt;/span&gt; CronExpression(&lt;span class="str"&gt;"* * * L * ?"&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; Assert.IsTrue(exp.IsSatisfiedBy(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2000,
1, 31)));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; Assert.IsTrue(exp.IsSatisfiedBy(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2000,
2, 29)));&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; Assert.IsFalse(exp.IsSatisfiedBy(&lt;span class="kwrd"&gt;new&lt;/span&gt; DateTime(2000,
2, 28)));&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=982dfdf2-cec1-462b-b160-0f8876ce7958" /&gt;</description>
      <comments>http://www.felicepollano.com/CommentView,guid,982dfdf2-cec1-462b-b160-0f8876ce7958.aspx</comments>
      <category>Cron</category>
      <category>Programmin</category>
      <category>Recipes</category>
    </item>
    <item>
      <trackback:ping>http://www.felicepollano.com/Trackback.aspx?guid=d6073d99-5b6b-4082-af1d-abaf9d534ba8</trackback:ping>
      <pingback:server>http://www.felicepollano.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.felicepollano.com/PermaLink,guid,d6073d99-5b6b-4082-af1d-abaf9d534ba8.aspx</pingback:target>
      <dc:creator>Felice Pollano</dc:creator>
      <wfw:comment>http://www.felicepollano.com/CommentView,guid,d6073d99-5b6b-4082-af1d-abaf9d534ba8.aspx</wfw:comment>
      <wfw:commentRss>http://www.felicepollano.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d6073d99-5b6b-4082-af1d-abaf9d534ba8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Può succedere di dover specificare il nome di un assembly completo, magari in un file
di configurazione dell’applicativo. Sfortunatamente non si può tagliare ed incollare
la stringa dalla GAC, e bisogna copiare ed incollare i vari pezzi dalla finestra property. <a href="http://cid-b8821720666a55e7.skydrive.live.com/self.aspx/.Public/GacExplorer.zip" target="_blank">Ecco
quindi un piccolo tool</a> che mostra tutto il contenuto della GAC e ci permette di
copiare l’assembly full name. Eccolo all’opera:
</p>
        <p>
          <a href="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaCopiarelAssemblyFullyQUalifiedNam_B41B/gac_2.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="gac" border="0" alt="gac" src="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaCopiarelAssemblyFullyQUalifiedNam_B41B/gac_thumb.png" width="708" height="290" />
          </a>
        </p>
        <p>
Si accettano complimenti per la meravigliosa interfaccia utente ;).
</p>
        <p>
Nondimeno importante segnalare <a href="http://blogs.msdn.com/junfeng/articles/229649.aspx" target="_blank">lo
snapshot di codice che consente con facilità di maneggiare la GAC run-time</a>.
</p>
        <img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=d6073d99-5b6b-4082-af1d-abaf9d534ba8" />
      </body>
      <title>Ricetta:Copiare l’AssemblyFullyQUalifiedName dalla GAC</title>
      <guid isPermaLink="false">http://www.felicepollano.com/PermaLink,guid,d6073d99-5b6b-4082-af1d-abaf9d534ba8.aspx</guid>
      <link>http://www.felicepollano.com/2010/05/20/RicettaCopiareLAssemblyFullyQUalifiedNameDallaGAC.aspx</link>
      <pubDate>Thu, 20 May 2010 10:48:35 GMT</pubDate>
      <description>&lt;p&gt;
Può succedere di dover specificare il nome di un assembly completo, magari in un file
di configurazione dell’applicativo. Sfortunatamente non si può tagliare ed incollare
la stringa dalla GAC, e bisogna copiare ed incollare i vari pezzi dalla finestra property. &lt;a href="http://cid-b8821720666a55e7.skydrive.live.com/self.aspx/.Public/GacExplorer.zip" target="_blank"&gt;Ecco
quindi un piccolo tool&lt;/a&gt; che mostra tutto il contenuto della GAC e ci permette di
copiare l’assembly full name. Eccolo all’opera:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaCopiarelAssemblyFullyQUalifiedNam_B41B/gac_2.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="gac" border="0" alt="gac" src="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaCopiarelAssemblyFullyQUalifiedNam_B41B/gac_thumb.png" width="708" height="290"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Si accettano complimenti per la meravigliosa interfaccia utente ;).
&lt;/p&gt;
&lt;p&gt;
Nondimeno importante segnalare &lt;a href="http://blogs.msdn.com/junfeng/articles/229649.aspx" target="_blank"&gt;lo
snapshot di codice che consente con facilità di maneggiare la GAC run-time&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=d6073d99-5b6b-4082-af1d-abaf9d534ba8" /&gt;</description>
      <comments>http://www.felicepollano.com/CommentView,guid,d6073d99-5b6b-4082-af1d-abaf9d534ba8.aspx</comments>
      <category>Programmin</category>
      <category>Recipes</category>
    </item>
    <item>
      <trackback:ping>http://www.felicepollano.com/Trackback.aspx?guid=96eea3f9-55bc-440b-9d1e-82aaf9e7de1c</trackback:ping>
      <pingback:server>http://www.felicepollano.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.felicepollano.com/PermaLink,guid,96eea3f9-55bc-440b-9d1e-82aaf9e7de1c.aspx</pingback:target>
      <dc:creator>Felice Pollano</dc:creator>
      <wfw:comment>http://www.felicepollano.com/CommentView,guid,96eea3f9-55bc-440b-9d1e-82aaf9e7de1c.aspx</wfw:comment>
      <wfw:commentRss>http://www.felicepollano.com/SyndicationService.asmx/GetEntryCommentsRss?guid=96eea3f9-55bc-440b-9d1e-82aaf9e7de1c</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="justify">
Può essere interessante, quando si sviluppano e si utilizzano in modalità test servizi
di windows, avere una modalità di funzionamento “Console”, che ci permetta di lanciare
il nostro servizio come una console application per vedere “cosa fa” senza stare lì
ad aprire ogni secondo il file di log. Ovviamente dobbiamo prevedere un sistema di
logging che scriva anche sulla console  (se per loggare usate <a href="http://logging.apache.org/log4net/index.html" target="_blank">log4net</a>,
allora basta mettere un <strong>ConsoleAppender</strong>, o meglio ancora, un <strong>ColoredConsoleAppender</strong>).
Per farlo basta creare la solita WindowsServiceApplication, avendo però cura di impostare
il progetto come console:
</p>
        <p align="justify">
          <a href="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaWindowsServiceInterattivoquandol_83FF/consoleapp_2.png">
            <img style="border: 0px none; display: inline;" title="consoleapp" alt="consoleapp" src="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaWindowsServiceInterattivoquandol_83FF/consoleapp_thumb.png" border="0" width="419" height="54" />
          </a>
        </p>
        <p>
Il main dovrà essere modificato in questoi modo
</p>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[]
args)</pre>
          <pre>
            <span class="lnum"> 2: </span> {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span>
            <span class="kwrd">if</span> (!Environment.UserInteractive)</pre>
          <pre>
            <span class="lnum"> 4: </span> {</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> log.Info(<span class="str">"Starting
as a service..."</span>);</pre>
          <pre>
            <span class="lnum"> 6: </span> ServiceBase[] ServicesToRun;</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> ServicesToRun
= <span class="kwrd">new</span> ServiceBase[] </pre>
          <pre>
            <span class="lnum"> 8: </span> { </pre>
          <pre class="alt">
            <span class="lnum"> 9: </span>
            <span class="kwrd">new</span> Service1() </pre>
          <pre>
            <span class="lnum"> 10: </span> };</pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> ServiceBase.Run(ServicesToRun);</pre>
          <pre>
            <span class="lnum"> 12: </span> }</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span>
            <span class="kwrd">else</span>
          </pre>
          <pre>
            <span class="lnum"> 14: </span> {</pre>
          <pre class="alt">
            <span class="lnum"> 15: </span> log.Info(<span class="str">"Starting
as a console..."</span>);</pre>
          <pre>
            <span class="lnum"> 16: </span> var s = <span class="kwrd">new</span> Service1(log);</pre>
          <pre class="alt">
            <span class="lnum"> 17: </span> s.GetType().GetMethod( <span class="str">"OnStart"</span></pre>
          <pre>
            <span class="lnum"> 18: </span> ,BindingFlags.Instance|BindingFlags.NonPublic</pre>
          <pre class="alt">
            <span class="lnum"> 19: </span> ).Invoke(s,<span class="kwrd">new</span><span class="kwrd">object</span>[]{args});</pre>
          <pre>
            <span class="lnum"> 20: </span> Console.WriteLine(<span class="str">"Press
enter to exit the console mode"</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 21: </span> Console.ReadLine();</pre>
          <pre>
            <span class="lnum"> 22: </span> s.GetType().GetMethod( <span class="str">"OnStop"</span></pre>
          <pre class="alt">
            <span class="lnum"> 23: </span> ,
BindingFlags.Instance | BindingFlags.NonPublic</pre>
          <pre>
            <span class="lnum"> 24: </span> ).Invoke(s, <span class="kwrd">null</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 25: </span> }</pre>
          <pre>
            <span class="lnum"> 26: </span> }</pre>
          <pre> </pre>
          <pre> </pre>
          <pre> </pre>
          <div align="justify">
            <p>
Alla linea 3 il codice che ci permette di capire se siamo stati lanciati da uno user
“vero” o dal sistema,e quindi scegliamo se partire nel modo tradizionale oppure in
modalità console. Se a questo codice aggiungiamo anche la possibilità di interpretare
la command line e di <a href="http://www.felicepollano.com/2010/05/03/RicettaServizioAutoInstallante.aspx" target="_blank">autoinstallarsi</a>,
abbiamo un buon segmento di codice da riusarsi per ogni WindowService.
</p>
          </div>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=96eea3f9-55bc-440b-9d1e-82aaf9e7de1c" />
      </body>
      <title>Ricetta: WindowsService Interattivo quando lanciato dall’utente.</title>
      <guid isPermaLink="false">http://www.felicepollano.com/PermaLink,guid,96eea3f9-55bc-440b-9d1e-82aaf9e7de1c.aspx</guid>
      <link>http://www.felicepollano.com/2010/05/06/RicettaWindowsServiceInterattivoQuandoLanciatoDallutente.aspx</link>
      <pubDate>Thu, 06 May 2010 07:23:11 GMT</pubDate>
      <description>&lt;p align="justify"&gt;
Può essere interessante, quando si sviluppano e si utilizzano in modalità test servizi
di windows, avere una modalità di funzionamento “Console”, che ci permetta di lanciare
il nostro servizio come una console application per vedere “cosa fa” senza stare lì
ad aprire ogni secondo il file di log. Ovviamente dobbiamo prevedere un sistema di
logging che scriva anche sulla console&amp;nbsp; (se per loggare usate &lt;a href="http://logging.apache.org/log4net/index.html" target="_blank"&gt;log4net&lt;/a&gt;,
allora basta mettere un &lt;strong&gt;ConsoleAppender&lt;/strong&gt;, o meglio ancora, un &lt;strong&gt;ColoredConsoleAppender&lt;/strong&gt;).
Per farlo basta creare la solita WindowsServiceApplication, avendo però cura di impostare
il progetto come console:
&lt;/p&gt;
&lt;p align="justify"&gt;
&lt;a href="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaWindowsServiceInterattivoquandol_83FF/consoleapp_2.png"&gt;&lt;img style="border: 0px none; display: inline;" title="consoleapp" alt="consoleapp" src="http://www.felicepollano.com/public/WindowsLiveWriter/RicettaWindowsServiceInterattivoquandol_83FF/consoleapp_thumb.png" border="0" width="419" height="54"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Il main dovrà essere modificato in questoi modo
&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[]
args)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (!Environment.UserInteractive)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; log.Info(&lt;span class="str"&gt;"Starting
as a service..."&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; ServiceBase[] ServicesToRun;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; ServicesToRun
= &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceBase[] &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; { &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Service1() &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt; };&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; ServiceBase.Run(ServicesToRun);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; log.Info(&lt;span class="str"&gt;"Starting
as a console..."&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; var s = &lt;span class="kwrd"&gt;new&lt;/span&gt; Service1(log);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; s.GetType().GetMethod( &lt;span class="str"&gt;"OnStart"&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt; ,BindingFlags.Instance|BindingFlags.NonPublic&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; ).Invoke(s,&lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;object&lt;/span&gt;[]{args});&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; Console.WriteLine(&lt;span class="str"&gt;"Press
enter to exit the console mode"&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; Console.ReadLine();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; s.GetType().GetMethod( &lt;span class="str"&gt;"OnStop"&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 23: &lt;/span&gt; ,
BindingFlags.Instance | BindingFlags.NonPublic&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 24: &lt;/span&gt; ).Invoke(s, &lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 25: &lt;/span&gt; }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 26: &lt;/span&gt; }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;div align="justify"&gt;
&lt;p&gt;
Alla linea 3 il codice che ci permette di capire se siamo stati lanciati da uno user
“vero” o dal sistema,e quindi scegliamo se partire nel modo tradizionale oppure in
modalità console. Se a questo codice aggiungiamo anche la possibilità di interpretare
la command line e di &lt;a href="http://www.felicepollano.com/2010/05/03/RicettaServizioAutoInstallante.aspx" target="_blank"&gt;autoinstallarsi&lt;/a&gt;,
abbiamo un buon segmento di codice da riusarsi per ogni WindowService.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=96eea3f9-55bc-440b-9d1e-82aaf9e7de1c" /&gt;</description>
      <comments>http://www.felicepollano.com/CommentView,guid,96eea3f9-55bc-440b-9d1e-82aaf9e7de1c.aspx</comments>
      <category>Recipes</category>
    </item>
    <item>
      <trackback:ping>http://www.felicepollano.com/Trackback.aspx?guid=d244d0aa-c2d5-4237-b849-8f0b830f1ac8</trackback:ping>
      <pingback:server>http://www.felicepollano.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.felicepollano.com/PermaLink,guid,d244d0aa-c2d5-4237-b849-8f0b830f1ac8.aspx</pingback:target>
      <dc:creator>Felice Pollano</dc:creator>
      <wfw:comment>http://www.felicepollano.com/CommentView,guid,d244d0aa-c2d5-4237-b849-8f0b830f1ac8.aspx</wfw:comment>
      <wfw:commentRss>http://www.felicepollano.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d244d0aa-c2d5-4237-b849-8f0b830f1ac8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p align="justify">
Quando andiamo in deploy con un servizio C# abbiamo l’opzione di utilizzare installutil.exe
per “installare” il servizio, ovvero far si che compaia nel Service Control Manager.
Tuttavia è possibile fare la stessa cosa programmaticamente, e farlo semplifica la
vita a chi installera il vostro servizio. L’idea è che il main del servizio risponda
a dei comandi sulla cmd line, per esempio <strong>“—install”</strong> o <strong>“—uninstall” </strong>in <strong>modo 
che l’unico strumento che serve in fase di deploy sia il servizio stesso</strong>.
</p>
        <p align="justify">
Ecco dunque la ricetta: si deve intendere “ricetta” come un segmento di codice troppo
piccolo da essere messo in una libreria, ma troppo importante per essere dimenticato
:-)
</p>
        <p align="justify">
La ricetta in oggetto è quindi composta di due funzioni:
</p>
        <h3>Install()
</h3>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> Install()</pre>
          <pre>
            <span class="lnum"> 2: </span> {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> ServiceProcessInstaller
ProcesServiceInstaller = <span class="kwrd">new</span> ServiceProcessInstaller();</pre>
          <pre>
            <span class="lnum"> 4: </span> ProcesServiceInstaller.Account
= ServiceAccount.LocalSystem;</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span>
          </pre>
          <pre>
            <span class="lnum"> 6: </span> ServiceInstaller
ServiceInstallerObj = <span class="kwrd">new</span> ServiceInstaller();</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> InstallContext
Context = <span class="kwrd">new</span> System.Configuration.Install.InstallContext();</pre>
          <pre>
            <span class="lnum"> 8: </span> String
path = String.Format(<span class="str">"/assemblypath={0}"</span>, Assembly.GetExecutingAssembly().Location);</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> String[]
cmdline = { path };</pre>
          <pre>
            <span class="lnum"> 10: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> Context
= <span class="kwrd">new</span> System.Configuration.Install.InstallContext(<span class="str">""</span>,
cmdline);</pre>
          <pre>
            <span class="lnum"> 12: </span> ServiceInstallerObj.Context =
Context;</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span> ServiceInstallerObj.DisplayName
= <span class="str">"Nome da visualizzare in SCM"</span>;</pre>
          <pre>
            <span class="lnum"> 14: </span> ServiceInstallerObj.Description
= <span class="str">"Descrizione del servizio"</span>;</pre>
          <pre class="alt">
            <span class="lnum"> 15: </span> ServiceInstallerObj.ServiceName
= <span class="str">"NomeDelServizio"</span>;</pre>
          <pre>
            <span class="lnum"> 16: </span> ServiceInstallerObj.StartType
= ServiceStartMode.Automatic;</pre>
          <pre class="alt">
            <span class="lnum"> 17: </span> ServiceInstallerObj.Parent
= ProcesServiceInstaller;</pre>
          <pre>
            <span class="lnum"> 18: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 19: </span> System.Collections.Specialized.ListDictionary
state = <span class="kwrd">new</span> System.Collections.Specialized.ListDictionary();</pre>
          <pre>
            <span class="lnum"> 20: </span>
          </pre>
          <pre class="alt">
            <span class="lnum"> 21: </span> ServiceInstallerObj.Install(state);</pre>
          <pre>
            <span class="lnum"> 22: </span> }</pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
        </p>
        <h3>Uninstall()
</h3>
        <div class="csharpcode">
          <pre class="alt">
            <span class="lnum"> 1: </span>
            <span class="kwrd">private</span>
            <span class="kwrd">static</span>
            <span class="kwrd">void</span> Uninstall()</pre>
          <pre>
            <span class="lnum"> 2: </span> {</pre>
          <pre class="alt">
            <span class="lnum"> 3: </span> ServiceProcessInstaller
ProcesServiceInstaller = <span class="kwrd">new</span> ServiceProcessInstaller();</pre>
          <pre>
            <span class="lnum"> 4: </span> ProcesServiceInstaller.Account
= ServiceAccount.LocalSystem;</pre>
          <pre class="alt">
            <span class="lnum"> 5: </span> </pre>
          <pre>
            <span class="lnum"> 6: </span> ServiceInstaller
ServiceInstallerObj = <span class="kwrd">new</span> ServiceInstaller();</pre>
          <pre class="alt">
            <span class="lnum"> 7: </span> InstallContext
Context = <span class="kwrd">new</span> System.Configuration.Install.InstallContext();</pre>
          <pre>
            <span class="lnum"> 8: </span> String
path = String.Format(<span class="str">"/assemblypath={0}"</span>, Assembly.GetExecutingAssembly().Location);</pre>
          <pre class="alt">
            <span class="lnum"> 9: </span> String[]
cmdline = { path };</pre>
          <pre>
            <span class="lnum"> 10: </span> </pre>
          <pre class="alt">
            <span class="lnum"> 11: </span> Context
= <span class="kwrd">new</span> System.Configuration.Install.InstallContext(<span class="str">""</span>,
cmdline);</pre>
          <pre>
            <span class="lnum"> 12: </span> ServiceInstallerObj.Context =
Context;</pre>
          <pre class="alt">
            <span class="lnum"> 13: </span> ServiceInstallerObj.ServiceName
= <span class="str">"ServiceName"</span>;</pre>
          <pre>
            <span class="lnum"> 14: </span> ServiceInstallerObj.Uninstall(<span class="kwrd">null</span>);</pre>
          <pre class="alt">
            <span class="lnum"> 15: </span> </pre>
          <pre>
            <span class="lnum"> 16: </span> }</pre>
          <pre> </pre>
        </div>
        <style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
        <p>
Importante: Per entrambe le funzioni, <strong>ServiceName</strong> deve essere uguale
alla proprietà <strong>ServiceName del servizio che si vuole installare</strong>.
</p>
        <img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=d244d0aa-c2d5-4237-b849-8f0b830f1ac8" />
      </body>
      <title>Ricetta:Servizio Auto-Installante</title>
      <guid isPermaLink="false">http://www.felicepollano.com/PermaLink,guid,d244d0aa-c2d5-4237-b849-8f0b830f1ac8.aspx</guid>
      <link>http://www.felicepollano.com/2010/05/03/RicettaServizioAutoInstallante.aspx</link>
      <pubDate>Mon, 03 May 2010 09:46:55 GMT</pubDate>
      <description>&lt;p align="justify"&gt;
Quando andiamo in deploy con un servizio C# abbiamo l’opzione di utilizzare installutil.exe
per “installare” il servizio, ovvero far si che compaia nel Service Control Manager.
Tuttavia è possibile fare la stessa cosa programmaticamente, e farlo semplifica la
vita a chi installera il vostro servizio. L’idea è che il main del servizio risponda
a dei comandi sulla cmd line, per esempio &lt;strong&gt;“—install”&lt;/strong&gt; o &lt;strong&gt;“—uninstall” &lt;/strong&gt;in &lt;strong&gt;modo&amp;nbsp;
che l’unico strumento che serve in fase di deploy sia il servizio stesso&lt;/strong&gt;.
&lt;/p&gt;
&lt;p align="justify"&gt;
Ecco dunque la ricetta: si deve intendere “ricetta” come un segmento di codice troppo
piccolo da essere messo in una libreria, ma troppo importante per essere dimenticato
:-)
&lt;/p&gt;
&lt;p align="justify"&gt;
La ricetta in oggetto è quindi composta di due funzioni:
&lt;/p&gt;
&lt;h3&gt;Install()
&lt;/h3&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Install()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; ServiceProcessInstaller
ProcesServiceInstaller = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceProcessInstaller();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; ProcesServiceInstaller.Account
= ServiceAccount.LocalSystem;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; ServiceInstaller
ServiceInstallerObj = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceInstaller();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; InstallContext
Context = &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Configuration.Install.InstallContext();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; String
path = String.Format(&lt;span class="str"&gt;"/assemblypath={0}"&lt;/span&gt;, Assembly.GetExecutingAssembly().Location);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; String[]
cmdline = { path };&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; Context
= &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Configuration.Install.InstallContext(&lt;span class="str"&gt;""&lt;/span&gt;,
cmdline);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; ServiceInstallerObj.Context =
Context;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; ServiceInstallerObj.DisplayName
= &lt;span class="str"&gt;"Nome da visualizzare in SCM"&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; ServiceInstallerObj.Description
= &lt;span class="str"&gt;"Descrizione del servizio"&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt; ServiceInstallerObj.ServiceName
= &lt;span class="str"&gt;"NomeDelServizio"&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; ServiceInstallerObj.StartType
= ServiceStartMode.Automatic;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 17: &lt;/span&gt; ServiceInstallerObj.Parent
= ProcesServiceInstaller;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 18: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 19: &lt;/span&gt; System.Collections.Specialized.ListDictionary
state = &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Collections.Specialized.ListDictionary();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 20: &lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 21: &lt;/span&gt; ServiceInstallerObj.Install(state);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 22: &lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Uninstall()
&lt;/h3&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 1: &lt;/span&gt; &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Uninstall()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 2: &lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 3: &lt;/span&gt; ServiceProcessInstaller
ProcesServiceInstaller = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceProcessInstaller();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 4: &lt;/span&gt; ProcesServiceInstaller.Account
= ServiceAccount.LocalSystem;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 5: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 6: &lt;/span&gt; ServiceInstaller
ServiceInstallerObj = &lt;span class="kwrd"&gt;new&lt;/span&gt; ServiceInstaller();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 7: &lt;/span&gt; InstallContext
Context = &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Configuration.Install.InstallContext();&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 8: &lt;/span&gt; String
path = String.Format(&lt;span class="str"&gt;"/assemblypath={0}"&lt;/span&gt;, Assembly.GetExecutingAssembly().Location);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 9: &lt;/span&gt; String[]
cmdline = { path };&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 10: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 11: &lt;/span&gt; Context
= &lt;span class="kwrd"&gt;new&lt;/span&gt; System.Configuration.Install.InstallContext(&lt;span class="str"&gt;""&lt;/span&gt;,
cmdline);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 12: &lt;/span&gt; ServiceInstallerObj.Context =
Context;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 13: &lt;/span&gt; ServiceInstallerObj.ServiceName
= &lt;span class="str"&gt;"ServiceName"&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 14: &lt;/span&gt; ServiceInstallerObj.Uninstall(&lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 15: &lt;/span&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt; 16: &lt;/span&gt; }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
&lt;p&gt;
Importante: Per entrambe le funzioni, &lt;strong&gt;ServiceName&lt;/strong&gt; deve essere uguale
alla proprietà &lt;strong&gt;ServiceName del servizio che si vuole installare&lt;/strong&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.felicepollano.com/aggbug.ashx?id=d244d0aa-c2d5-4237-b849-8f0b830f1ac8" /&gt;</description>
      <comments>http://www.felicepollano.com/CommentView,guid,d244d0aa-c2d5-4237-b849-8f0b830f1ac8.aspx</comments>
      <category>Recipes</category>
    </item>
  </channel>
</rss>