Archivi tag: Plugin

Inno Setup & Browser Helper Objects & IE Toolbars

In un mio recente progetto, ho avuto la necessità di creare ,per Internet Explorer, un Browser Helper Object (un plugin che sfrutta le stesse interfacce e tecnologie delle Toolbar) che eseguisse delle operazioni custom su un particolare sito in ambiente Intranet.
La realizzazione del BHO, è relativamente semplice usando le interfacce IObjectWithSite e le direttive di interoperabilità del codice.
Per il setup invece è tutto particolarmente difficile. Le interfacce del BHO vanno registrate nel registry di Windows e rese accessibili al sistema di plugin di IE.
Per far questo ho usato un software free, INNO SETUP, che permette di generare degli installer a partire da uno script.
Inno Setup

Lo script, permette di definire il comportamento del setup, le informazioni da visualizzare nelle maschere, e tutte le operazioni da effettuare sul registry di Windows, compresa la problematica di differenze di posizionamento e nome di alcune voci tra i sistemi a 32 e a 64 bit. Il Bho di cui realizzo il setup è compilato in maniera da funzionare compatibilmente con tutti i sistemi e quindi richiede un setup compatibile sia con i sistemi a 32 che a 64 bit.

Lo script inizia con una serie di definizioni di costanti usate poi nel resto delle direttive, tra cui il nome della dll, il nome del namespace utilizzato, e il nome della classe interna che viene esposta al browser, contenente i metodi pubblici da utilizzare.

1
2
3
4
5
6
7
8
9
#define MyAppDescription "My Helper Objects"
#define MyAppName "MyBHO"
#define MyAppVersion "1.0.0.0"
#define MyAppPublisher "Metalide"
#define MyAppURL "http://www.metalide.com"
#define MyAppDllName "MyBHO.dll"
#define MyAppId "{A80C384E-4178-4AD0-85BC-3196241437C5}"
#define MyAppNamespace "MyBHO.MyHelperObject"
#define MyAppClass "MyBHOExtension"

Subito dopo si crea una sezione [Setup] per associare le costanti ai parametri dell’installer e altri attributi:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Setup]
AppId={#MyAppName}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\MyTools\MyHelperObjects
DefaultGroupName=My_IETOOLS
DisableProgramGroupPage=yes
DisableDirPage=yes
CreateAppDir=yes
OutputBaseFilename=My_IETOOLSBHOSetup
Compression=lzma
SolidCompression=yes

Viene poi impostata la lingua del setup e il path di destinazione della dll (che in questo caso va registrata nella GAC di Windows), e l’eventuale icona da usare per le voci di unistall:

1
2
3
4
5
6
7
8
[Languages]
Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl"

[Files]
Source: "D:\Dev\MyBho\MyBHOBHOSETUP\MyBHO.dll"; DestDir: "{app}"; Flags: ignoreversion

[Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"

Fatto questo si passa alla sezione [Code] che mantiene delle funzioni (sono scritte in Pascal) generiche richiamate dai metodi “hook” gestiti da Inno stesso,come ad esempio il methodo InitializeSetup che viene eseguito a startup dell’installazione.
In questa sezione ho messo un metodo per la rilevazione dell’installazione su sistemi a 64 e 32 bit e sulla verifica del framework .net installato (il bho che ho realizzato in c# richiede, visto il codice managed, la presenza di .net 4.0)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[Code]
function IsDotNetDetected(version: string; service: cardinal): boolean;
//    'v1.1.4322'     .NET Framework 1.1
//    'v2.0.50727'    .NET Framework 2.0
//    'v3.0'          .NET Framework 3.0
//    'v3.5'          .NET Framework 3.5
//    'v4\Client'     .NET Framework 4.0 Client Profile
//    'v4\Full'       .NET Framework 4.0 Full Installation
//service: per la presenza richiesta di service pack:
//    0               No service packs
//    1, 2, etc.      Service pack 1, 2, etc..
var
    key: string;
    install, serviceCount: cardinal;
    success: boolean;
begin
    key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + version;
    // .NET 3.0 usa InstallSuccess nella chiave Setup
    if Pos('v3.0', version) = 1 then begin
        success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install);
    end else begin
        success := RegQueryDWordValue(HKLM, key, 'Install', install);
    end;
    // .NET 4.0 usa Servicing al posto di SP
    if Pos('v4', version) = 1 then begin
        success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount);
    end else begin
        success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount);
    end;
    result := success and (install = 1) and (serviceCount >= service);
end;



function Install32BitOn64Bit(S: String):string;
begin
    if IsWin64 then
      Result := 'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{#MyAppId}'
    else
      Result := 'Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{#MyAppId}'
end;

function InitializeSetup(): Boolean;
begin
  if  IsDotNetDetected('v4\Client', 0) or  IsDotNetDetected('v4\Full', 0) then
      Result :=true
  else begin
      MsgBox('Attenzione Framework .NET 4.0 non rilevato', mbError, mb_Ok);
      Result :=false;
     end
 
end;

Come ultimo step del nostro script andiamo ad indicare nella sezione [Registry] tutte le chiavi da impostare (e sono molte) per il funzionamento del nostro componente come plugin di IE. Il guid che si passa, è il guid associato serve a indicare i componenti .net.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[Registry]
Root: HKCR; Subkey: "CLSID\{{#MyAppId}"; Flags: uninsdeletekey
Root: HKCR; Subkey: "CLSID\{{#MyAppId}"; ValueType: string; ValueName: ; ValueData: {#MyAppNamespace}
Root: HKCR; Subkey: "CLSID\{{#MyAppId}"; ValueType: string; ValueName: MenuText; ValueData: {#MyAppName}
Root: HKCR; Subkey: "CLSID\{{#MyAppId}"; ValueType: string; ValueName: HelpText; ValueData: {#MyAppDescription}
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\Implemented Categories\{{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}"
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: ; ValueData: mscoree.dll
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: ThreadingModel; ValueData: Both
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: Class; ValueData: {#MyAppNamespace}
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: CodeBase; ValueData: file:///{pf}\MyTools\MyBrowserHelperObjects\{#MyAppDllName}
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: Assembly; ValueData: {#MyAppName}, Version={#MyAppVersion}, Culture=neutral, PublicKeyToken=dedfcbc464c1d691
Root: HKCR; Subkey: "CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: RuntimeVersion; ValueData: v4.0.30319

Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}"; Flags: uninsdeletekey
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}"; ValueType: string; ValueName: ; ValueData: {#MyAppNamespace}
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}"; ValueType: string; ValueName: MenuText; ValueData: {#MyAppName}
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}"; ValueType: string; ValueName: HelpText; ValueData: {#MyAppDescription}
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\Implemented Categories\{{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}"
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: ; ValueData: mscoree.dll
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: ThreadingModel; ValueData: Both
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: Class; ValueData: {#MyAppNamespace}
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: CodeBase; ValueData: file:///{pf}\MyTools\MyBrowserHelperObjects\{#MyAppDllName}
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: Assembly; ValueData: {#MyAppName}, Version={#MyAppVersion}, Culture=neutral, PublicKeyToken=dedfcbc464c1d691
Root: HKLM; Subkey: "Software\Classes\CLSID\{{#MyAppId}\InprocServer32"; ValueType: string; ValueName: RuntimeVersion; ValueData: v4.0.30319

Root: HKLM; Subkey: {code:Install32BitOn64Bit};  Flags: uninsdeletekey
Root: HKLM; Subkey: {code:Install32BitOn64Bit}; ValueType: dword; ValueName: NoExplorer; ValueData: 1

Fatto questo, eseguendo lo script dal compilatore di Inno Setup, è possibile ottenere l’installer/uninstaller del nostro componente.

Ovviamente questo tutorial è il frutto di molte ricerche sulla rete, e di riferimenti presi da diversi blogger che hanno affrontato l’argomento, a cui vanno i miei ringraziamenti, e a quel pozzo infinito di spunti e riflessioni che è la comunità di StackOverflow, a cui va la mia gratitudine eterna 🙂 .

Custom Sidebars in WordPress & Articoli singoli

Ci sono decine di plugin che permettono di gestire le sidebar di WordPress, in maniera dinamica associandole alle categorie, o alle pagine , altri tramite logica configurabile, altri banalmente tramite un custom tag nella pagina.

Il problema fondamentale è che nei template standard non c’e’ supporto per le sidebar sulla visualizzazione di un singolo articolo.

Per sbloccare questa cosa bisogna apportare delle modifiche ai files del nostro tema.

Innanzitutto bisogna abilitare la sidebar nella pagina singola.

Apriamo il file single.php e aggiungiamo la funzione get_sidebar() prima della get_footer()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
/**
* The Template for displaying all single posts.
*
* @package WordPress
* @subpackage Twenty_Eleven
* @since Twenty Eleven 1.0
*/


get_header(); ?>

<div id="primary">

<div id="content" role="main">

<?php while ( have_posts() ) : the_post(); ?>

<nav id="nav-single">

<h3 class="assistive-text"><?php _e( 'Post navigation', 'twentyeleven' ); ?></h3>

<span class="nav-previous"><?php previous_post_link( '%link', __( '<span class="meta-nav">&larr;</span> Previous', 'twentyeleven' ) ); ?></span>

<span class="nav-next"><?php next_post_link( '%link', __( 'Next <span class="meta-nav">&rarr;</span>', 'twentyeleven' ) ); ?></span>

</nav><!-- #nav-single -->

<?php get_template_part( 'content', 'single' ); ?>

<?php comments_template( '', true ); ?>

<?php endwhile; // end of the loop. ?>

</div><!-- #content -->

</div><!-- #primary -->

<?php get_sidebar(); ?>

<?php get_footer(); ?>

Ora anche gli articoli quando visualizzati da soli (quindi non in modalità archivio, ricerca o homepage), avranno accesso alle sidebar.

Bisogna a questo punto aggiungere una funzione di decorazione del dom di pagina affinche vengano impostate le classi giuste del css altrimenti la sidebar verrà mostrata sotto l’articolo.

Apriamo quindi il file functions.php del nostro tema e in coda, aggiungiamo questa funzione:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
add_filter('body_class', 'fix_body_class_for_sidebar', 20, 2);

function fix_body_class_for_sidebar($wp_classes, $extra_classes) {

if( is_single() || is_page() ){

if (in_array('singular',$wp_classes)){

foreach($wp_classes as $key => $value) {

if ($value == 'singular')

unset($wp_classes[$key]);

}

}

}

return array_merge($wp_classes, (array) $extra_classes);

}

Fatto questo, il gioco è fatto.

Consiglio di usare poi, Content Aware Sidebar o Dynamics Sidebar come plugin per la gestione delle sidebar.

 

 

Configurare Symphonic Choirs & Wordbuilder in Logic Studio

Dopo essere letteralmente impazzito nel tentativo di farlo funzionare, aver cercato in lungo e largo, sono finalmente arrivato ad un metodo funzionante.

Se avete Symphonic Choirs della EastWest, e volete farlo funzionare con il WordBuilder (il tool per la creazione di parole per i cori), e logic studio 9, ecco dei semplici passi da seguire.

Innanzitutto eseguite l’installazione di tutta la suite (circa 40 giga di roba).

Poi dovrete procurarvi un nuovo player per i multi files di Symphonic Choirs perche il plugin nativo è troppo vecchio e non viene visto da Logic Studio. Io ho preso Native Instruments Kontakt Player 4.0 che e’ piu che sufficiente.

Fate partire WorldBuilder e selezionate questi settings:

Poi selezioniamo una frase di test da quelle disponibili in latino

 

Ora che abbiamo preparato Wordbuilder passiamo a Logic Studio .

Facciamolo partire con un nuovo progetto, e prepariamo due tracce:

La prima traccia è una traccia External Midi che faremo puntare alla porta di WorldBuilder1

La seconda traccia invece è un Software Instrument . Andiamo Sulla sezione di I/O della traccia e carichiamo il plugin player Kontakt 4.0

Si aprirà il plugin.

Nella sezione di configurazione , andiamo ad impostre il path dei multi (i pacchetti di suoni) di Symphonic Choirs:

A questo punto carichiamo le voci di Symphonic Choirs.

I multi da caricare sono quelli che hanno nel nome le lettere WB (wordbuilder).

Selezioniamole dai Basses cosi come abbiamo scelto sul wordbuilder:

Ora dobbiamo configurare le rotte midi su Logic Studio, per far questo apriamo la finestra dell’environment (command 8)

Dalla vista Mixer, copiamo la traccia con il software instrument dei cori

poi dal menu in alto cambialo visualizzazione e andiamo a click & ports.

qui incolliamo il canale del software instrument

Poi selezioniamo il canale del wordbuilder1 e lo colleghiamo al canale appena incollato e cancelliamo il link sul “Sum”

Prendiamo invece la CapsLock Keyboard  e lo colleghiamo con la tastiera midi nell’interfaccia, e selezioniamo poi tutti i tasti della tastiera in modo da registrare tutti gli eventi midi associati .

Fatto questo il plugin è configurato. Torniamo alla nostra finestra di Arrange e selezionando la prima traccia e premendo il tasto capslock siamo in grado di far apparire la tastiera midi e suonare qualcosa che riproduca le frasi impostate sul wordbuilder.

Mettendo questa frase sul wordbuilder

mo r!E t!O rE t!e Sa lO t!ant!

(il votox di Morituri te Salutant)

ecco cosa esce fuori:

MORITURI