software-on-demand-ita.com

Giuseppe Pischedda

Software Engineer

software-on-demand-ita.com

Giuseppe Pischedda

Software Engineer

Porting Win32 applications to the Microsoft Store with Desktop App Converter

How to convert classic Win32 applications for the Microsoft Store.

Part 1



Col Desktop Bridge Microsoft dà la possibilità di fare il porting di applicazioni e games dalla classica piattaforma Win32 allo Store.
Naturalmente, sebbene una classica applicazione Win32 per desktop possa essere ammessa nel Microsoft Store, questa non diventa un'applicazione UWP (Universal Windows Platform), piuttosto essa verrà inserita in package (un file compresso) il quale potrà essere installato in Windows 10.

E' possibile predisporre un'applicazione Win32 in un package per lo Store o per l'installazione sideload in due modi:

  • Manualmente, usando il tool Desktop App Converter
  • Col supporto per Visual Studio 2017 (vers.15.9)

Una volta convertita e "impacchettata" l'applicazione può essere distribuita attraverso due canali:

  • Microsoft Store
  • Sideload


Il processo conversione di un'applicazione avviene in due passaggi:

  • 1) Esecuzione del tool Desktop App Converter
  • 2) Esecuzione del tool Windows App Certification Kit

Per poter essere accettata nello Store, la nostra applicazione Win32 deve avere precisi requisiti (consultare il sito Microsoft).
La certificazione di un'applicazione convertita per lo Store è a discrezione di Microsoft che, quand è il caso, comunica gli aspetti critici da correggere per poterla accettare o ne rigetta il package.

Per essere certi che un' applicazione sia idonea per lo Store è necessario sottoporla ai medesimi test a cui sarà sottoposta da Microsoft stessa, ed allo scopo, c'è un altro tool che verifica se l'applicazione convertita potrà essere certificata: Windows App Certification Kit.

Nella parte 2 di questo tutorial vedremo che Visual Studio 2017 integra i due tools ed in maniera automatica crea tutta l'infrastruttura necessaria per la conversione e la certificazione di un'applicazione Windows desktop.



Partenza

1)
Se nel vostro sistema non avete già installato il tool Desktop App Converter installatelo.

2)
Creiamo in Visual Studio 2017 un nuovo progetto Win32 Desktop così strutturato:

  • un exe
  • due dll
  • nella directory di deploy ci dovrà essere subdirectory in cui metteremo un file di help.
  • un paio di files a corredo dell'applicazione (readme.txt e license.txt)

Struttura della directory di deploy

RootFolder\
    |
    |
    exe
    dll_1
    dll_2
    txt_1
    txt_2
    |
    |
    HelpFolder\
        |
        |----
             help.html
                |
                |
             HelpFolderSubdir\
                     |
                     |----
                          file_1
                          file_2
                         

            

Nota
Lo scopo di avere un progetto che sia così strutturato ( punto 2 ) lo capiremo meglio nella parte 2 di questo tutorial quando vedremo come aggiungere al package gestito da Visual Studio 2017 dei files a corredo dell'applicazione. Per ora sappiate che Visual Studio 2017 inserisce nel package di default il solo file exe, tutto il resto che fa parte integrante dell'applicazione (dlls etc.) no.



Crieamo l'applicazione Win32 "DoNothingApp" da convertire per lo Store
Nota
Per comodità userò un template per Visual Studio che creerà un progetto Win32 Dialog Application C/C++.
Scaricate ed installate il template da questo stesso sito all'indirizzo:

Apriamo Visual Studio 2017, dal menu File -> New Project -> Visual C++ -> Win32DlgProject


VC++ Project Template


Chiamerò il progetto DoNothingApp

DoNothingApp Project Start DoNothingApp Project Running



Settiamo Solution Configuration a Release, quindi dal menu Project scegliamo DoNothingApp Properties

DoNothingApp Release DoNothingApp Project Properties


andiamo al nodo Manifest Tool alla voce Input and Output

  • nell'opzione Additional Manifest Files settiamo (*) win10-and-dpi.xml
  • nell'opzione DPI Awareness settiamo Per Monitor High DPI Aware

DoNothingApp Manifest

Eseguiamo questo stesso passaggio per entrambe le configurazioni (Release Win32 e Release x64).

* Nota
Il file win10-and-dpi.xml integra il file manifest dell'applicazione e contiene le dichiarazioni di compatibilità con Windows 10 (ed altre versioni di Windows).
Le impostazioni di compatibilità del file manifest e DPI Awareness sono necessarie in quanto il tool Windows App Cert Kit verificherà tra le altre cose se è stata dichiarata la compatibilità con Windows 10 nel file manifest e che l'applicazione sia compatibile con i monitors ad alta risoluzione (oltre i 96 dpi).

<!-- win10-and-dpi.xml file content -->


<assembly>
       <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
      
      <!-- Windows 10 -->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

      <!-- Windows 8.1 -->>
       <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />

      <!-- Windows Vista -->
        <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />

      <!-- Windows 7 -->
        <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />

      <!-- Windows 8 -->
        <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />

    </application>
  </compatibility>
</assembly>



Aggiungiamo due progetti DLL Win32 al progetto DoNothingApp


Aggiungiamo alla soluzione i due progetti DLL Win32 che chiameremo MyDLL_1 e MyDLL_2

DoNothingApp Add DLL DoNothingApp Add DLL


Aggiungiamo due semplici funzioni da esportare in entrambe le dll


// MyDLL_1.h : Defines the exported functions for the DLL application.
//
#pragma once

#include "stdafx.h"

__declspec(dllexport) VOID MyDLL_1_GetMessage();


//-----------------------------------------------------------


// MyDLL_1.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "MyDLL_1.h"


__declspec(dllexport) VOID MyDLL_1_GetMessage()
{
	MessageBox(0, L"Hello from MyDLL_1", L"Message", MB_OK);
}

// MyDLL_2.h : Defines the exported functions for the DLL application.
//
#pragma once

#include "stdafx.h"

__declspec(dllexport) VOID MyDLL_2_GetMessage();


//--------------------------------------------------


// MyDLL_2.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "MyDLL_2.h"


__declspec(dllexport) VOID MyDLL_2_GetMessage()
{
	MessageBox(0, L"Hello from MyDLL_2", L"Message", MB_OK);
}


Includiamo gli headers delle due dll nel progetto DoNothingApp

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

.......
.......

#include "..\MyDLL_1\stdafx.h"
#include "..\MyDLL_2\stdafx.h"

#pragma comment(lib,"MyDLL_1.lib")
#pragma comment(lib,"MyDLL_2.lib")





Aggiungiamo nella dialog 2 Buttons dalla Toolbox

DoNothingApp Add Buttons


Implementiamo l'evento OnClick di entrambi i buttons:

//MainFuncDialog.h

..........
..........

//DLLs imported functions
__declspec(dllimport) VOID MyDLL_1_GetMessage();
__declspec(dllimport) VOID MyDLL_2_GetMessage();


//MainDialogFunc.cpp

..........
..........

case IDC_BUTTON1:
MyDLL_1_GetMessage();
break;

		
case IDC_BUTTON2:
MyDLL_2_GetMessage();
break;




Settiamo l'ordine di build dei tre progetti:

DoNothingApp Build Order DoNothingApp Build Order DoNothingApp Build Order

In project properties settiamo la directory dove il linker potrà trovare i files MyDLL_1.lib e MyDLL_2.lib


DoNothingApp Linker Setting


Mandiamo in run l'applicazione

DoNothingApp Running DoNothingApp Running DoNothingApp Running


Ora nella cartella Release abbiamo (tra gli altri) il file exe e le due dll


DoNothingApp Release Folder


Creiamo i due file (readme.txt e license.txt) a corredo dell'applicazione


DoNothingApp Add Txt Files DoNothingApp Add Txt Files DoNothingApp Add Txt Files DoNothingApp Add Txt Files


I due file txt sono stati creati e si trovano nella stessa directory del progetto DoNothingApp.

DoNothingApp Add Txt Files


Tuttavia (per comodità) vogliamo che tutti i files che fanno parte dell'applicazione risiedano nella stessa cartella di deploy che nel caso del progetto x86 è la cartella Project_Name\Release mentre per la versione x64 è Project_Name/x64/Release.


A tale scopo settiamo nel progetto DoNothingApp un Post-Build Event. Chiederemo a Visual Studio di copiare i due files txt nella stessa cartella di deploy del progetto. Il settaggio dovrà essere ripetuto per entrambe le configurazioni Release x86 ed x64.

DoNothingApp Txt Files Post-Buld Event DoNothingApp Txt Files Post-Buld Event


Per mettere ordine (visivamente) al progetto DoNothingApp aggiungiamo un nuovo nodo (filtro) dentro cui sposteremo (facendo drag&drop) i due files txt.


DoNothingApp Txt Files Post-Buld Event DoNothingApp Txt Files Post-Buld Event


Eseguito il rebuild della soluzione, le directories ...\Release e ...\x64\Release contengono tutti i files che fanno parte della nostra applicazione nelle versioni rispettivamente x86 ed x64.


DoNothingApp Deploy Folder


Creazione manuale del package col tool Desktop App Converter


Per comodità copiamo il file exe le due dll e i due txt files in una cartella facilmente raggiungibile via commandline che chiameremo donothingapp.

Nella cartella donothingapp creiamo le cartelle packagesourcex86, packagesourcex64, packageoutx86 e packageoutx64
In packagesourcexXX metteremo i files da inserire nei packages (rispettivamente x86 e x64), nella cartella packageoutxXX troveremo i rispettivi packages alla fine del processo di creazione.


DoNothingApp Deploy Folder DoNothingApp Deploy Folder DoNothingApp Deploy Folder


Avviamo il tool Desktop App Converter con i diritti di Administrator e cancelliamo il testo di help di default.


Desktop App Converter Desktop App Converter


I parametri del tool sono molti e variano a seconda del package che vogliamo creare. Per i nostri scopi useremo i seguenti:

  • -Installer (cartella in cui si trovano i files da mettere nel package)
  • -AppExecutable (nome del file exe)
  • -Destination (cartella di output del package)
  • -PackageName (nome del package per il sistema)
  • -Publisher (nome del publisher per il sistema)
  • -Version (versione del package)
  • -MakeAppx (esegue lo strumento MakeAppx)
  • -Appid (id dell'app)
  • -PackageDisplayName (nome del package per l'utente)
  • -PackagePublisherDisplayName (nome del publisher per l'utente)
  • -AppDisplayName (nome dell'app per l'utente)
  • -AppDescription (descrizione dell'app)


Nota

Quando si riserva il nome dell'applicazione per lo Store questo assegna dei valori univoci simili ai seguenti (da assegnare obbligatoriamente ai parametri qui sotto, pena il rigetto della validazione del package da parte dello strumento di verifica packages dello Store)

  • PackageName (00000YourName.AppName)
  • Publisher (CN=00000000-AAAA-0A00-000A-000A00000A00)
  • Appid (dovrà essere il suffisso dopo il punto del parametro PackageName, nell'esempio qui sopra AppName)
Dato che comunque la nostra applicazione di esempio (DoNothingApp) non dovrà essere pubblicata nello Store e non ha un nome riservato, possiamo usare dei valori di fantasia.



Componiamo la nostra commandline per il tool ed eseguiamo:



DoNothingApp package x86

DesktopAppConverter.exe -Installer D:\donothingapp\packagesourcex86 -AppExecutable "DoNothingApp.exe" -Destination D:\donothingapp\packageoutx86\DoNothingApp -PackageName "DoNothingAppx86.DoNothingApp" -Publisher "CN=Your Name Here" -Version 1.0.0.0 -MakeAppx  -Appid "DoNothingApp" -PackageDisplayName "DoNothing App" -PackagePublisherDisplayName "YourName Here" -AppDisplayName "DoNothing App" -AppDescription "How useless is this application?"


    


Desktop App Converter


DoNothingApp package x64


DesktopAppConverter.exe -Installer D:\donothingapp\packagesourcex64 -AppExecutable "DoNothingApp.exe" -Destination D:\donothingapp\packageoutx64\DoNothingApp -PackageName "DoNothingAppx64.DoNothingApp" -Publisher "CN=Your Name Here" -Version 1.0.0.0 -MakeAppx  -Appid "DoNothingApp" -PackageDisplayName "DoNothing App" -PackagePublisherDisplayName "YourName Here" -AppDisplayName "DoNothing App" -AppDescription "How useless is this application?" 


Desktop App Converter

Nota
DesktopAppConverter emette un warning avvisandoci che non tutti i devices supportano applicazioni a 64 bit.

I due packages sono stati creati:


Desktop App Converter Desktop App Converter




Project Dependencies

DoNothingApp è un'applicazione C++ Win32 che dipende (volutamente) dal runtime di Visual C++ 2017 la cui presenza nella macchina dei nostri users è necessaria, tuttavia non è possibile installare il classico runtime VC++ 2017, magari prelevato dal sito Microsoft od incorporato in un programma di setup.
Per ovviare, dovremo dichiarare nel file xml di entrambe le configurazioni (x86 ed x64) che la nostra applicazione dipende da tale runtime e quindi produrre un nuovo package.

Andiamo nel percorso D:\donothingapp\packageoutx86\DoNothingApp\DoNothingAppx86.DoNothingApp\PackageFiles

Apriamo il file AppxManifest.xml e cerchiamo il nodo <Dependencies> ed all'interno di questo aggiungiamo:

<PackageDependency Name="Microsoft.VCLibs.140.00.UWPDesktop" MinVersion="14.0.24217.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />


Desktop App Converter Desktop App Converter Desktop App Converter


Ripetiamo l'operazione per il file di configurazione x64.
Ora, quando verrà richiesto di installare la nostra app verrà verificata la presenza di VC++ 2017 e qualora non ci fosse, l'utente sarà invitato ad installare il runtime.




Rifare i packages
Una volta apportate modifiche al file manifest del package è necessario ricrearlo.
Per farlo useremo il tool MakeAppx, il tool a riga di comando che troviamo tra gli strumenti della SDK di Windows 10.

Avviamo dunque una sessione del prompt dei comandi di Visual Studio e rifacciamo entrambi i packages:


x86


makeappx pack -d "D:\donothingapp\packageoutx86\DoNothingApp\DoNothingAppx86.DoNothingApp\PackageFiles" -p "D:\donothingapp\packageoutx86\DoNothingApp\DoNothingAppx86.DoNothingApp\DoNothingAppx86.DoNothingApp.appx"

MakeAppx


x64


makeappx pack -d "D:\donothingapp\packageoutx64\DoNothingApp\DoNothingAppx64.DoNothingApp\PackageFiles" -p "D:\donothingapp\packageoutx64\DoNothingApp\DoNothingAppx64.DoNothingApp\DoNothingAppx64.DoNothingApp.appx"



I nuovi package sono stati creati.

MakeAppx


Ora è necessario validare i due packages con il tool Windows App Cert Kit


Dopo aver avviato il tool, scegliamo l'opzione "Validate Store App"


Windows App Cert Kit


Selezioniamo il nostro primo package, lasciamo le impostazioni de default (tutti i test selezionati).
Una volta finita la validazione avremo il responso.


Windows App Cert Kit Windows App Cert Kit Windows App Cert Kit Windows App Cert Kit Windows App Cert Kit Windows App Cert Kit


Conclusa positivamente la validazione dei due packages (x86 e x64) possiamo procedere all'installazione nella nostra macchina di test tramite la seguente riga di comando in una sessione di PowerShell con diritti di Admin:


Add-AppxPackage –Register AppxManifest.xml


Nota
E' possibile anche installare il package facendo doppio click sul file .appx. A tale scopo è necessario firmare il package con un certificato autoprodotto.
Il certificato va poi installato nella macchina di test come attendibile.

DoNohingApp Install DoNohingApp Install



Viceversa, utilizzando PowerShell non è necessario firmare il package in fase di test.



DoNohingApp Install DoNohingApp Install DoNohingApp Installed


Nella parte 2 di questo tutorial vedremo come Visual Studio 2017 (vers. 15.9 minimo) consenta la conversione di applicazioni nate per desktop in applicazioni compatibili con Microsoft Store in maniera molto più semplice e diretta.


Processing request, please wait...


Download DoNothingApp part-1 Source




Giuseppe Pischedda 2018


Ehi, se ti va puoi offrirmi un caffè.


Ehi, se ti va puoi offrirmi un caffè.

Informativa estesa art.13 d.lgs. 196/03 ed art. 13 del Regolamento UE 2016/679 del 27 aprile 2016 (privacy)