+ Rispondi al Thread
Visualizzazione dei risultati da 1 a 6 su 6

Discussione: Distribuzione applicazione WinForm C#

  1. #1
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    191

    Distribuzione applicazione WinForm C#

    Buonasera a tutti,

    purtroppo ne Google ne il cerca sul forum mi hanno aiutato, e quindi mi rivolgo a voi.
    Ho sviluppato una piccola app che stampa delle etichette tramite una Dymo LabelWriter 450. Nessun errore in compilazione e debug approfondito effettuato. Funziona tutto.

    Ora vorrei distribuire questa piccola app tra i client delle mia LAN, e ho pensato di utilizzare ClickOnce, così da evitare anche di gestirmi gli aggiornamenti che farò in futuro (l'attuale versione è stabile ma vorrei ampliarla con altre funzionalità) e non avere l'incombenza di doverla installare io in qualità di amministratore.

    Impostato il percorso di pubblicazione, facendolo puntare ad una cartella dedicata sul server, dal client lancio il file setup.exe e non ottengo errori di sorta. Ho impostato durante il wizard l'uso offline dell'applicazione e quindi mi ritrovo correttamente l'icona nel pannello Start di Win8.1 Pro.

    Al momento di lanciare l'app, questa non si avvia e non mi viene riportato nessun errore. Per fare qualche tentativo trovato in rete, sempre tramite Wizard ho tentato di pubblicare l'app sia con, che senza la firma dell'assembly e dei manifesti ClickOnce. Nada!

    Ho sviluppato l'app su un PC con Win8.1 pro e utilizzo Visual Studio Community 2017. La mia versione del :NET Framework è 4.7.03062, ma ho impostato:
    - framework di destinazione a 4.6.1
    - Tipo di output: Applicazione Windows
    - Oggetto di avvio: Etichette.program
    I client su cui ho provato ad effettuare l'installazione hanno le stessa configurazioni di SO, ma non hanno l'installazione di VS.

    Ho tentato anche di copiare la cartella [bin/release] sul client di destinazione ma continuo a non veder partire l'app e a non ricevere errori di sorta. L'unica cosa che percepisco è un leggero sfarfallio della finestra dell'esplora risorse che ho usato per individuare e clicckare il file EXE creato da VS.

    Sicuramente sto saltando qualche passaggio importante, ma onestamente sono alla mia prima distribuzione e non ho ben idea di come muovermi.

    Sapreste aiutarmi in qualche modo?

    Grazie in anticipo

    Carmine

  2. #2
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,110
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Al momento di lanciare l'app, questa non si avvia e non mi viene riportato nessun errore.
    In poche parole, non vedi nulla a schermo e l'applicazione non parte, né viene mostrato alcun messaggio di errore, neanche di crash?

    Come primo step, analizzerei cosa cerchi di fare nell'avvio dell'applicazione, oppure al momento della creazione del Form principale della stessa, poiché magari quel passaggio contiene chiamate che fanno fallire la corretta inizializzazione del programma.

    In secondo luogo, prova ad aggiungere un qualsivoglia sistema di log, anche rudimentale, che scriva su file di testo i passaggi eseguiti, così da capire meglio dove può inchiodarsi il programma, magari catturando le eventuali eccezioni che si possono verificare sempre all'inizializzazione del programma e del Form principale.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  3. #3
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    191
    Ciao Marco e grazie per i suggerimenti!
    Quote Originariamente inviato da _alka_ Visualizza il messaggio
    In poche parole, non vedi nulla a schermo e l'applicazione non parte, né viene mostrato alcun messaggio di errore, neanche di crash?
    Esattamente...
    Quote Originariamente inviato da _alka_ Visualizza il messaggio
    Come primo step, analizzerei cosa cerchi di fare nell'avvio dell'applicazione, ...

    In secondo luogo, prova ad aggiungere un qualsivoglia sistema di log, ...
    Ho seguito i tuoi consigli e ho prodotto quanto segue:
    in primis, ho implementato questa piccola classe per gestirmi in autonomia il Log delle operazioni:
    codice:
        class Logger : IDisposable
        {
            StreamWriter logFile;
            public Logger() : this(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)) { }
            public Logger(string path)
            {
                logFile = new StreamWriter(Path.Combine(path, "log" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".txt"));
                Scrivi("File di log generato correttamente!");
            }
            public void Scrivi(string stringa)
            {
                logFile.Write(DateTime.Now.ToLongTimeString()+": ");
                logFile.WriteLine(stringa);
            }
            public void Dispose()
            {
                logFile.Write("StreamWriter rilasciato alle: " + DateTime.Now.ToLongTimeString());
                logFile.Dispose();
            }
        }
    In secundis, ho modificato il punto di entrata del programma:
    codice:
        static class Program
        {
            private static Logger log;
    
            /// <summary>
            /// Punto di ingresso principale dell'applicazione.
            /// </summary>
            [STAThread]
            static void Main()
            {
                log = new Logger(AppDomain.CurrentDomain.BaseDirectory);
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
                log.Dispose();
            }
            public static Logger Log { get { return log; } }
        }
    Risultato: il file txt viene correttamente creato, ma resta vuoto... Non esegue nemmeno la scrittura della prima riga che dovrebbe risultare dalla chiamata a
    codice:
    Scrivi("File di log generato correttamente!");
    che si trova nel costruttore del Logger. La cosa che mi lascia perplesso è che se crea il file txt la chiamata al costruttore la esegue, ma se resta vuoto, non la completa!

    In modalità Debug/Release sulla mia macchina funziona tutto alla perfezione, il file viene creato e scritto...

    Proverò a gestire anche le eccezioni che potrebbero derivare dalle chiamate ai metodi
    codice:
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new Form1());
    ma ho paura di fare un lavoro a vuoto visto che sul log non scrive proprio niente.

  4. #4
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,110
    Io opterei per una soluzione più semplice e - almeno per il momento - meno configurabile, altrimenti si rischia di dover spostare l'attenzione dal problema iniziale a quello che riguarda il funzionamento del logger, e così non se ne esce.

    In breve, definisci un percorso fisso per il file di log, magari in una costante, e accontentati di fare una File.AppendAllText passando direttamente il percorso e la stringa da accodare, così sei certo di non introdurre altre problematiche da diagnosticare; nel tuo esempio infatti, rischi che il file venga scritto nella stessa directory dell'eseguibile, e questo non è concesso a meno di non eseguire il programma con diritti amministrativi (e dando la conferma alla finestra dell'UAC).

    Screma l'implementazione e lascia solo l'essenziale che deve funzionare per forza.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  5. #5
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    191
    Grazie! Con le tue dritte ci sono arrivato

    Ho sfruttato il costruttore del Logger che crea il file nella cartella Documenti dell'utente della macchina. Poi ho modificato il codice dell'ingresso al programma come di seguito:

    codice:
            static void Main()
            {
                log = new Logger();
                Application.EnableVisualStyles();
                try
                {
                    Application.SetCompatibleTextRenderingDefault(false);
                }
                catch(Exception ex)
                {
                    log.Scrivi("Errore in Application.SetCompatibleTextRenderingDefault(false)");
                    log.Scrivi(ex.Message);
                    log.Dispose();
                }
    
                try
                {
                    Application.Run(new Form1());
                }
                catch (Exception ex)
                {
                    log.Scrivi("Errore in Application.Run(new Form1())");
                    log.Scrivi(ex.Message);
                    log.Dispose();
                }
                if(!log.IsDisposed)
                    log.Dispose();
    Mi sono ritrovato finalmente con le eccezioni intercettate e scritte nel file, così ho capito che il problema del crash silenzioso era dovuto alla mancanza del Framework DYMO sugli altri client.
    Onestamente non avevo previsto questa eventualità, pensando che la distribuzione con ClickOnce sopperisse da sola all'installazione librerie mancanti, ma probabilmente non ho capito qualcosa al riguardo. Ho installato manualmente le librerie sui client e l'applicazione funziona perfettamente.

    Ora procederò nel fare piccole modifiche all'interfaccia e vedere se almeno gli aggiornamenti se li gestisce in automatico, come da me impostato durante il wizard della distribuzione.

    Grazie mille Marco!!

  6. #6
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,110
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Mi sono ritrovato finalmente con le eccezioni intercettate e scritte nel file, così ho capito che il problema del crash silenzioso era dovuto alla mancanza del Framework DYMO sugli altri client.
    Onestamente non avevo previsto questa eventualità, pensando che la distribuzione con ClickOnce sopperisse da sola all'installazione librerie mancanti, ma probabilmente non ho capito qualcosa al riguardo. Ho installato manualmente le librerie sui client e l'applicazione funziona perfettamente.
    Purtroppo ClickOnce non gestisce queste eventualità, a meno che qualcuno non ne introduca il supporto in Visual Studio grazie a qualche estensione o plugin.

    La tecnologia si preoccupa principalmente di "impacchettare" tutto ciò che sono eseguibili, dipendenze ed eventuali setting del progetto .NET; eventuali "wrapper" per librerie di terze parti verrebbero inclusi, ma se si tratta di librerie che si interfacciano a DLL native, OCX o altre tecnologie che esulano dal contesto .NET, la procedura non è in grado di individuarli e devono subire un deploy separato, che è possibile usando tool più avanzati - tipo InstallShield - che sono magari in grado di allargare il bacino e gestire il deploy del programma principale, di librerie di terze parti, di setting, file addizionali e quant'altro serve all'applicazione per funzionare.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

+ Rispondi al Thread

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi