Oppure

Loading
04/10/21 20:32
Gemini
Salve a tutti sono nuovo del forum e sto appena incominciando a programmare in c#.... ho creato un programma che avvia un processo esterno e mi reindirizza l'output... diciamo che qualcosa sono riuscito a farlo però non capisco perchè dopo avermi mandato l'output si chiude il processo...io invece vorrei che lo tiene aperto e semai mi se cambia qualcosa mi reindirizza altri output su una richbox......
Vi mostro il codice che ho fatto così da aiutarmi a farmi capire dove sto sbagliando.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rAthenaConsole
{
    public partial class mainForm : Form
    {


        //=====================================================================
        //== Main Form 
        //=====================================================================
        public mainForm()
        {

            InitializeComponent();
        }



        //=====================================================================
        //== Bottone Start 
        //=====================================================================
        private void btn_startServer_Click(object sender, EventArgs e)
        {
            Run("V:\miacartella\programma.exe");
        }



        //=====================================================================
        //== Bottone Stop  
        //=====================================================================
        private void btn_stopServer_Click(object sender, EventArgs e)
        {

        }


        //=====================================================================
        //== Funzione Run
        //=====================================================================
        void Run(string pathProcess)
        {
            try
            {

                //Char Server
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = pathProcess,
                        //Arguments = "behavior query SymlinkEvaluation",
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true
                    }
                };

                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    var line = process.StandardOutput.ReadLine();
                    rtb_outProcess.AppendText(line);
                }

                process.WaitForExit();

            }
            catch (Exception o)
            {
                Console.WriteLine(o.Message);
            }
      
        }

       

    }
}




Un'altra cosa ho provato a creare un metodo così da potergli passare come parametro l'indirizzo del processo esterno da avviare però quando ne avvio piu di uno mi si blocca il programma.... ovviamente li ho eseguiti in thread diversi....
05/10/21 6:47
Thejuster
oh, Ragnarok sta tornando di moda allora :rotfl:
Bello vedere spuntare di tanto in tanto qualcuno ancora interessato a questo gioco.

Ho fatto qualcosa del genere ma in c++ mentre imparavo un pò l'ide del qt.

github.com/Thejuster/…

Cerchiamo di capire prima cosa hai fatto.


Un'altra cosa ho provato a creare un metodo così da potergli passare come parametro l'indirizzo del processo esterno da avviare però quando ne avvio piu di uno mi si blocca il programma.... ovviamente li ho eseguiti in thread diversi....


Li hai eseguiti in Thread differenti, quindi tentare di accedere ad una risorsa o meglio dire Controllo utente
questo causa il Cross Thread Exception.

In Teoria saprei già scriverti la soluzione,Ma non serivrebbe a nulla se non capisci dove hai sbagliato.
Mostra anche la parte in cui esegui i Thread diversi ed il comportamento di questi Thread.

Ultima modifica effettuata da Thejuster 05/10/21 9:16
mire.forumfree.it/ - Mire Engine
C# UI Designer
05/10/21 18:30
Gemini
oh, Ragnarok sta tornando di moda allora :rotfl:
Bello vedere spuntare di tanto in tanto qualcuno ancora interessato a questo gioco.

Beh si xD anche se come grafica è un pò vecchiotta però e un gioco fatto molto bene a mio parere xP.....e si ci sono italiani che giocano ancora...io ne conosco un bel pò

Li hai eseguiti in Thread differenti, quindi tentare di accedere ad una risorsa o meglio dire Controllo utente
questo causa il Cross Thread Exception.


Allora si in pratica visto che è un pò scocciante e brutto il fatto di avere le tre finestre aperte sul desktop quando avvii il server di rAthena, allora provai a usare rAthenaConsole se nn sbaglio così si chiamava sul forum di rAthena ma caricava in modo lento i tre file bat cioè ti dico che ci metteva un 10min 15 pure LOL ed è un po tanto ma è un tools datato e quindi ho pensato di fare un programma in c# che mi avviava il srerver mostrandomi l'output su diverse richbox e magari aggiungiere anche qualche bottone dove poter resettare e stoppare senza chiudere le finestre e riaprirle...

però ora mi limito ad avviarlo xD
cmq posto il codice.... in pratica ho usato i Task che so che sono come Thread e ho passato i parametri però è un copia e incolla di una funzione niente di che(nella crezione di un metodo senza fare copia e incolla ho trovato il problema che non posso mandare alla richbox un valore xke mi da errore) e quindi ho pensato di non postare e magari aprire un'altro topic
spero di essermi spiegato bene

comunque questo è il codice che ho fatto
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rAthenaConsole
{
    public partial class mainForm : Form
    {


        //=====================================================================
        //== Main Form 
        //=====================================================================
        public mainForm()
        {
            
           

            InitializeComponent();
        }



        //=====================================================================
        //== Bottone Start 
        //=====================================================================
        private void btn_startServer_Click(object sender, EventArgs e)
        {
            Task.Run(() => RunChar("V:\rAthena\char-server.exe"));
            Task.Run(() => RunMap("V:\rAthena\map-server.exe"));
            Task.Run(() => RunLogin("V:\rAthena\login-server.exe"));

            //Run("V:\miacartella\programma.exe");
        }



        //=====================================================================
        //== Bottone Stop  
        //=====================================================================
        private void btn_stopServer_Click(object sender, EventArgs e)
        {

        }


        //=====================================================================
        //== Funzione Run Char
        //=====================================================================
        void RunChar(string pathProcess)
        {
            try
            {

                //Char Server
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = pathProcess,
                        //Arguments = "behavior query SymlinkEvaluation",
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true
                    }
                };

                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    var line = process.StandardOutput.ReadLine();
                    rtb_charServer.AppendText(line);
                    //return line;
                }

                process.WaitForExit();

            }
            catch (Exception o)
            {
                Console.WriteLine(o.Message);
            }

      
        }

        //=====================================================================
        //== Funzione Run Map
        //=====================================================================
        void RunMap(string pathProcess)
        {
            try
            {

                //Char Server
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = pathProcess,
                        //Arguments = "behavior query SymlinkEvaluation",
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true
                    }
                };

                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    var line = process.StandardOutput.ReadLine();
                    rtb_mapServer.AppendText(line);
                    //return line;
                }

                process.WaitForExit();

            }
            catch (Exception o)
            {
                Console.WriteLine(o.Message);
            }


        }

        //=====================================================================
        //== Funzione Run Login
        //=====================================================================
        void RunLogin(string pathProcess)
        {
            try
            {

                //Char Server
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = pathProcess,
                        //Arguments = "behavior query SymlinkEvaluation",
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true
                    }
                };

                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    var line = process.StandardOutput.ReadLine();
                    rtb_loginServer.AppendText(line);
                    //return line;
                }

                process.WaitForExit();

            }
            catch (Exception o)
            {
                Console.WriteLine(o.Message);
            }


        }


    }
}




purtroppo ho letto alcune guide e questo sono riuscito a fare xD voglio capire xò dove sto sbagliando e come fare un programma simile fatto in modo corretto.... grazie per il supporto ^^
Ultima modifica effettuata da Gemini 05/10/21 18:39
05/10/21 18:32
Gemini
POST SBAGLIATO SCUSATEMI!!!
Ultima modifica effettuata da Gemini 05/10/21 18:34
06/10/21 10:21
Thejuster
dunque gemini, il codice in se' è corretto.
Ma manca un particolare importante.
Il WorkingDirectory.

Il WorkingDirectory e in pratica un opzione che indica come se il programma venisse lanciato da quella determinata cartella.

Lanciandolo invece dal tuo exe senza una working directory, l'eseguibile di eAthena non trova i file necessari per avviarsi.

Generalmente, si utilizzano percorsi relativi quando si sviluppa un'applicazione.
Quindi se cerchi di avviare un exe che deve leggere determinati file, e vari settaggi e utile settare una workingdirectory.

Con i Task, non mi trovo a mio agio.
Preferisco usare il classici Thread...

Sono la stessa cosa?
Diciamo che fanno la medisima cosa ma in modo differente.

Sono tradizionalista,preferisco le vecchie maniere che sono sempre le migliori.
Ancora preferisco scrivermi Motori 3D usando le DXSDK che utilizzare motori già fatti :rotfl:

Quindi al StartInfo, Aggiungi l'opzione WorkingDirectory al percorso dove è situato l'eseguibile che vuoi lanciare.

Ti ho fatto un piccolo esempio utilizzando i Thread al posto dei Task.
In allegato il zip

i.ibb.co/r4MmW1X/…
Ultima modifica effettuata da Thejuster 06/10/21 10:34
mire.forumfree.it/ - Mire Engine
C# UI Designer
06/10/21 17:08
Gemini
Grazie Thejuster mi piace come spieghi e fai capire le cose ^^..... comunque ho risolto grazie al tuo consiglio e grazie anche per l'esempio dell'invoke e delegate che andrò ad approfondire meglio.... comunque posto il mio codice l'ho modificato invece di usare 3 funzioni diverse per ogni processo ho creato una sola funzione che passo l'indirizzo del processo e un id che mi identifica il processo per postare sulla richbox giusta ogni output...è un po grezza voglio vedere se posso ritornare un id del thread o qualcosa di simile per evitare di passare al metodo Run il parametro idProcess. Poi vedrò un pò su google comunque ecco il codice e funziona perfettamente l'unica cosa se posso chidere non voglio andare fuori topic (ma è normale che ci mette molto ad avviare il server.? cioè se avvio il file bat runserver.bat ci mette 1 minuto? a caricare login char e map....mentre ho notato che anche con questo programma è lento nel caricare il map?? forse xke e un ritardo di output? ) xò non voglio andare fuori topic mi fermo qui e se puoi accenarmi qualcosa te ne sarei grato... ^^

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace rAthenaConsole
{
    public partial class mainForm : Form
    {

        Thread t_char, t_map, t_login;

        //=====================================================================
        //== Main Form 
        //=====================================================================
        public mainForm()
        {
            
           

            InitializeComponent();
        }



        //=====================================================================
        //== Bottone Start 
        //=====================================================================
        private void btn_startServer_Click(object sender, EventArgs e)
        {
            
            t_char = new Thread(() => Run(@"V:\rAthena\LOCAL\server\char-server.exe",1)); //Char
            t_map = new Thread(() => Run(@"V:\rAthena\LOCAL\server\map-server.exe", 2)); //Map
            t_login = new Thread(() => Run(@"V:\rAthena\LOCAL\server\login-server.exe", 3)); //Login

            t_char.Start();
            t_map.Start();
            t_login.Start();

        }



        //=====================================================================
        //== Bottone Stop  
        //=====================================================================
        private void btn_stopServer_Click(object sender, EventArgs e)
        {

        }


        //=====================================================================
        //== Metodo Run
        //=====================================================================
        private void Run(string processPath, int idProcess) //idProcess = || 1 Char || 2 Map || 3 Login || //Per identificare il processo e utilizzare diverse richbox
        {
            try
            {

                //Char Server
                var process = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = processPath,
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        CreateNoWindow = true,
                        WorkingDirectory = @"V:\rAthena\LOCAL\server"
                    }
                };

                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    if(idProcess == 1) //Char
                    {
                        Invoke(new Action(delegate { rtb_charServer.AppendText(process.StandardOutput.ReadLine() + "\n"); rtb_charServer.ScrollToCaret(); }));
                    }
                    else if (idProcess == 2) //Map
                    {
                        Invoke(new Action(delegate { rtb_mapServer.AppendText(process.StandardOutput.ReadLine() + "\n"); rtb_mapServer.ScrollToCaret(); }));
                    }
                    else if (idProcess == 3) //Login
                    {
                        Invoke(new Action(delegate { rtb_loginServer.AppendText(process.StandardOutput.ReadLine() + "\n"); rtb_loginServer.ScrollToCaret(); }));
                    }
                    else
                    {
                        Invoke(new Action(delegate { rtb_loginServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_loginServer.ScrollToCaret(); }));
                        Invoke(new Action(delegate { rtb_mapServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_mapServer.ScrollToCaret(); }));
                        Invoke(new Action(delegate { rtb_charServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_charServer.ScrollToCaret(); }));
                    }
                }

                process.WaitForExit();

            }
            catch (Exception o)
            {
                Console.WriteLine(o.Message);
            }
        }

    }
}


Ultima modifica effettuata da Gemini 06/10/21 17:09
06/10/21 18:57
Thejuster
No tranquillo,
Fin quando l'argomento è relativo al topic non si va in OT.

Il problema non dipende ne da te, e ne da me.
Puoi stare tranquillo che anche a me succede la stessa cosa.

Principalmente, dipende dal fatto che stai usando rAthena e non eAthena.
rAthena gira su un'architettura differente da eAthena.

Perché eAthena per i computer dell'epoca, era necessaria più velocità e leggerezza rispetto ad un moderno processore.
Quindi e stato progettato diversamente, ma anche con funzioni molto limitate.
Difatti puoi ricordare che gli NPC erano interpretati tramite un semplici comandi. molto differenti da ora che sono
interpretati dal LUA.

rAthena essendo a 64bit, ovviamente ha più potenziale e personalizzazioni rispetto al vecchio x86.
Ma ne risente il processore.

Oltre al fatto di essere stato completamente riscritto, sfrutta nuovi link moderni e librerie di interprete come il LUA.
che richiedono un pò di più per essere interpretati e messi in esecuzione in ram.
Questo anche perché il nuovo Client, è stato modificato per supportare il lua.

Quindi molte componenti del nuovo client agiscono tramite lua ed inviano pacchetti serializzati in modo differente.
per ottenere nuove grafiche come la nuova UI, le Quest, gli Archivement, ed integrazioni.

Insomma per dirla breve, il caricamento e lento perché il sistema di ri-elaborazione di script e di funzionalità e completamente diverso rispetto a prima.

Pensa che sono riuscito a modificare il sorgente di rAthena e realizzare un BOT Discord intercomunicante.
Nel senso che scrivi da discord, appare in gioco.
Scrivi dal gioco, appare in discord.

ecco, questo è un esempio di cosa si può fare e cosa non si può fare con il nuovo rAthena.
Screen allegata

in pratica ho virtualizzato un canale al posto di un nickname privato usando # come segnale di un canale discord.

Ultima modifica effettuata da Thejuster 06/10/21 18:59
mire.forumfree.it/ - Mire Engine
C# UI Designer
06/10/21 19:27
Gemini
sisi ho visto gia server che hanno implementato discord in game tipo novaro.... comunque vabbe non si può volere tutto nella vita xD mi arrangerò a questo problema..... ma un'altra cosa sempre senza andare OT ma ho provato a usare process.kill e process.Close.. sia in thread che senza ma non mi chiude i processi


  //=====================================================================
        //== Bottone Stop  
        //=====================================================================
        private void btn_stopServer_Click(object sender, EventArgs e)
        {
            /*t_char = new Thread(() => */Stop(@"V:\rAthena\LOCAL\server\char-server.exe", 1)); //Char
            /*t_map = new Thread(() => */Stop(@"V:\rAthena\LOCAL\server\map-server.exe", 2)); //Map
            /*t_login = new Thread(() => */Stop(@"V:\rAthena\LOCAL\server\login-server.exe", 3)); //Login




        //=====================================================================
        //== Metodo Stop
        //=====================================================================
        private void Stop(string processPath, int idProcess) //idProcess = || 1 Char || 2 Map || 3 Login || //Per identificare il processo e utilizzare diverse richbox
        {
            
            Process[] _proceses = null;
			_proceses = Process.GetProcessesByName(processPath);
			foreach (Process proces in _proceses)
			{
                 if (idProcess == 1) //Char
                    {
                        proces.Kill();
                    }
                     else if (idProcess == 2) //Map
                    {
                        proces.Kill();
                    }
                    else if (idProcess == 3) //Login
                    {
                        proces.Kill();
                    }
                    else
                    {
                        Invoke(new Action(delegate { rtb_loginServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_loginServer.ScrollToCaret(); }));
                        Invoke(new Action(delegate { rtb_mapServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_mapServer.ScrollToCaret(); }));
                        Invoke(new Action(delegate { rtb_charServer.AppendText("Errore nessun idProcess dichiarato\n"); rtb_charServer.ScrollToCaret(); }));
                    }
				
			}


anche se chiudo il programma normalmente devo chiudere i processi in gestione attività... sto vedendo un pò su internet ma tutti mi dicono di usare process.kill però non va.... forse sbaglio io qualcosa....sempre la WorkDirectory?