Porting Win32 applications to the Microsoft Store with Visual Studio 2017
Part 2
How to convert classic Win32 applications for the Microsoft Store.
Strutturare la Soluzione di Visual Studio
Nella parte 1 di questo tutorial abbiamo scritto un'applicazione Win32 DoNothingApp
che poi abbiamo impacchettato manualmente,
con lo strumento Desktop App Converter, in packages .appx (x86 e x64) pronti per essere distribuiti via Sideload o Microsoft Store.
La creazione manuale dei packages ha comportato una serie di passaggi
che invece Visual Studio 2017 avrebbe eseguito automaticamente.
Tale automatismo comunque necessita di una corretta struttura dell'intera soluzione affinchè
ciò che Visual Studio produce al posto nostro sia
perfettamente aderente alla struttura logica dell'applicazione.
Per fare un esempio, immaginiamo che la nostra applicazione una volta distribuita abbia una logica secondo la quale debba essere
obbligatoriamente strutturata
in una directory root e varie subdirectories in cui si trovano dll, file dati, file di database etc.
In tali casi, qualora la soluzione di Visual Studio non fosse ben strutturata, la nostra
applicazione verrebbe si inserita nei rispettivi packages (x86 / x64), ma sicuramente non avrebbe la struttura
logica che necessita (per esempio i files che dovrebbero trovarsi in una data subdirectory potrebbero invece
trovarsi nella directory root od all'esterno di essa e così via).
Inoltre ci sono altre complicazioni :
come indicare a Visual Studio i files che non siano exe affinchè vengano
inseriti nei packages? (Visual Studio automaticamente può impacchettare solo file exe), nonchè,
come fare inserire nei relativi packages, a Visual Studio, le corrette versioni (x86 ed x64)
di tutta la struttura logica della nostra applicazione?
Prima di vedere come rispondere ai quesiti qui sopra,
proseguiamo il progetto DoNothingApp
affinchè questo assuma la struttura desiderata
(vedi parte 1 alla sezione Struttura della directory di deploy).
Nota
Chi non fosse interessato ai vari passaggi relativi alla creazione da zero dell'applicazione DoNothingApp
descritti nella parte 1 può scaricare direttamente il progetto (parte 1) per Visual Studio 2017 a questo link:
e quindi proseguire da qui in avanti.
DoNothingApp Part 2
Apriamo il progetto DoNothingApp e per prima cosa facciamo in modo che
si possano facilmente distinguere le versioni x86 ed x64 dell'applicazione.
Faremo in modo che visualizzando le proprietà dei file della nostra app in Windows Explorer,
la versione x64 sia contrassegnata con la dicitura (vers. x64).
A tale scopo aggiungeremo alle risorse di ogni progetto due nuove risorse di tipo Version.
Assicuriamoci di aver selezionato in Solution Configurations
Release e x86
Selezioniamo il progetto, facciamo click sulla tab Resource poi click destro sul progetto DoNothingApp -> Add -> Resource.
Ora in Properties del progetto apriamo il nodo Resources -> General -> Preprocessor Definition
ed aggiungiamo una nuova definizione: DONOTHINGAPPVERS_X86 (assicuriamoci che la configurazione
sia Release e Win32) quindi salviamo.
Rimaniamo in Preprocessor Definition ma cambiamo configurazione scegliendo stavolta Release e x64.
Aggiungiamo una nuova definizione DONOTHINGAPPVERS_X64 e salviamo.
Selezioniamo la risorsa Version creata in precedenza, click destro su essa quindi in Properties
e nella proprietà Condition indichiamo la direttiva del preprocessore (per la versione x86).
Aggiungiamo una copia della risorsa facendo click destro sul nome della risorsa Version e quindi Insert Copy e
mettendo in Condition la direttiva per la versione x64 DONOTHINGAPPVERS_X64.
Modifichiamo il contenuto della risorsa Version aggiungendo la stringa vers. x64.
Ripetiamo il passaggio di creazione delle risorse Version per le due dll del progetto e
ricordiamo di aggiungere le direttive per il preprocessore nel nodo Resources di entrambe le dlls.
Quando finito ricompiliamo entrambe le configurazioni x86 ed x64.
Ora da proprietà file di Windows Explorer possiamo distinguere la versione x86 della nostra
applicazione da quella x64 (exe e dll).
Fatto ciò creaimo nella directory root della soluzione due cartelle che chiameremo dll_x86 e dll_x64.
In queste copieremo le rispettive versioni x86 e x64 delle nostre dll
e siccome vogliamo che le copie siano sempre aggiornate alla versone più recente
e certamente non vogliamo dopo ogni compilazione fare manualmente copia incolla, delegheremo questa
incombenza a Visual Studio assegnando un evento postbuild per entrambe le dlls e per ogni versione (x86 e x64).
Ricompiliamo entrambe le configurazioni x86 ed x64 e verifichiamo che Visual Studio abbia copiato corettamente nelle
relative cartelle le DLLs.
Aggiungiamo un Help System
Creiamo una nuova cartella nella directory root del progetto e chiamiamola Help.
All'interno di questa creiamo un help file di nome help_index e di tipo html quindi una subdirectory che conterrà i restanti file del
sistema di help.
Aggiungiamo al progetto DoNothingApp una voce di menu nelle risorse e gli impostiamo come ID : IDM_HELP
Aggiungiamo due includes:
#include <shellapi.h> #include <shlwapi.h>
implementiamo l'evento onclick del menu help:
...... ...... case IDM_HELP: { TCHAR szFileName[MAX_PATH]; GetModuleFileName(NULL, szFileName, MAX_PATH); PathRemoveFileSpec(szFileName); lstrcat(szFileName, L"\\Help\\help_index.htm"); SHELLEXECUTEINFO pExecInfo; pExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); pExecInfo.lpVerb = L"open"; pExecInfo.lpFile = szFileName; pExecInfo.fMask = NULL; pExecInfo.hwnd = NULL; pExecInfo.lpParameters = NULL; pExecInfo.lpDirectory = NULL; pExecInfo.nShow = SW_NORMAL; pExecInfo.hInstApp = NULL; ShellExecuteEx(&pExecInfo); } break; ....... .......
Ciò che fa questo pezzo di codice è elementare: ricava la directory corrente dell'applicazione
quindi la concatena con la sottodirectory Help e setta il nome del file da aprire help_index.htm,
infine chiede alla shell di Windows di aprire il file htm nel browser predefinito.
Naturalmente è necessario che la directory Help sia una sottodirectory della directory root dell'applicazione.
Da Win32 (exe) a UWP package
Ora che la struttura della soluzione DoNothingApp ha la forma attesa vediamo come creare
con Visual Studio 2017, partendo da un progetto Win32, i packages UWP (x86/x64) da distribuire via Microsoft Store o Sideload.
Alla soluzione DoNothingApp aggiungiamo un nuovo progetto dai templates Visual C++ -> Windows Universal
di tipo Windows Application Package Project
e di nome DoNothingAppDeploy.
Aggiungiamo la reference all'applicazione DoNothingApp.
Ora per vedere che succede creiamo i packages per lo Store:
dal menu Project -> Store -> Create App Packages, lasciamo tutto di default tranne lincremento automatico
del numero di versione e confermiamo la creazione dei packages
Ora se andiamo in esplora risorse vediamo che i packages sono stato creati ma il contenuto non è completo.
Mancano infatti le due DLLs, la cartella Help, il file htm, la relativa subdirectory html_index_file ed tutti i file
contenuti in essa.
Ciò è del tutto normale ed è dovuto al fatto che il progetto UWP della soluzione non può avere referenziati
i progetti delle nostre DLLs come avviene invece per il progetto dell'exe.
Per ovviare al problema aggiungiamo al progetto DoNothingApp due nuovi filtri i cui nomi
saranno (a titolo di esempio ovviamente): dlls_x86 e dlls_x64.
All'interno dei filtri aggiungiamo le rispettive dll (che si trovano nelle cartelle dlls_x86 e dlls_x64 create in precedenza).
Ora in entrambi i filtri abbiamo due dll.
Per ognuna di esse dovremo fare in modo che che:
- a) non partecipino al build
- b) facciano parte del contenuto del rispettivo progetto (x86 e x64)
Per chiarire meglio il punto b) qui sopra, si tratta semplicemente di far capire a Visual Studio 2017 che le versioni x86 delle dll devono essere incluse nel package UWP x86 e,ovviamente, le verisioni x64 nel package x64.
Allo scopo facciamo click destro sul nome della prima dll (MyDLL_1.dll) nel filtro dlls_x86 e scegliamo
Properties.
Nella dialog assicuriamoci che sia selezionato Configuration : Release e Win32.
Alla voce Content mettiamo YES.
Cambiamo Configuration da Win32 a x64 e mettiamo NO.
Per farla breve per ogni dll inclusa nei rispettivi filtri dlls_x86 e dlls_x64 si dovrà fare in modo che:
- le versioni x86 delle dll siano settate a YES nella riga Content nella configurazione Win32
- le versioni x86 delle dll siano settate a NO nella riga Content nella configurazione x64
- le versioni x64 delle dll siano settate a YES nella riga Content nella configurazione x64
- le versioni x64 delle dll siano settate a NO nella riga Content nella configurazione Win32
Concluso questo passaggio ripetiamo il deploy per lo store e stavolta le dll sono presenti
nella directory di ouput (e nei rispettivi packages x86 ed x64).
Per avere un'applicazione completa però manca all'appello ancora l'Help System, che anch'esso deve essere presente nella directory root dell'applicazione
e nei packages UWP.
Si tratta in pratica di includere la cartella Help e tutto il suo contenuto nei packages UWP e per far ciò
è sufficiente creare nel progetto UWP della soluzione DoNothingAppDeploy una nuova cartella il cui nome
però dev'essere obbligatoriamente identico a quello del progetto dell'applicazione (exe). Nel nostro caso
la nuova cartella avrà come nome DoNothingApp.
All'interno della directory DoNothingApp del progetto UWP DoNothingAppDeploy creiamo un'altra cartella
che chiameremo, appunto Help. Dentro quest'ultima aggiungiamo un item esistente: il file help_index.htm.
Sempre all'interno dell cartella Help creiamo un'altra cartella che chiameremo help_index_file.
All'interno della cartella help_index_file aggiungiamo tutti i restanti file dell'help system.
Creiamo nuovamente i packages : dal menu Project -> Store -> Create App Packages
Visual Studio ha creato per noi tutta l'infrastruttura (dipendenze da runtimes comprese) per la distribuzione dell'applicazione via Store o Sideload.
Il file .appxbundle (che è un file compresso) creato da Visual Studio, contiene (tra le altre cose) i due packages x86 ed x64 dell'applicazione
affinchè di essa venga installata, nella macchina dell'utente finale, la versione corretta per il sistema operativo di quest'ultimo.
Per distribuire la nostra applicazione dovremo semplicemente fare l'upload del file .appxbundle sul sito Partner Microsoft.
Chi non è iscritto al programma Partner Microsoft può distribuire in proprio il file .appxbundle (per esempio dal proprio sito web).
Processing request, please wait...
Giuseppe Pischedda 2018