Come si può modificare il codice da interfaccia utente?

di Edoardo998 il
19 risposte

19 Risposte - Pagina 2

  • 22/12/2022 - Edoardo998 ha scritto:


    Quindi come fanno questi software che hanno una sezione dove si può programmare?

    Hanno creato un linguaggio di programmazione intanto. Poi però ciò che scrivi lì in quella sezione non è un software a se stante, ma è in qualche modo integrato con il software principale. Perché poi i risultati vengono mostrati sul software principale.  

    Quanto chiedi è fattibilissimo utilizzando il .NET Framework, ma ovviamente richiede una “certa dimestichezza”, sia nell'uso degli strumenti preposti a questo scopo, sia alla modellazione dei tipi di dati che contengono le informazioni da rendere disponibili all'ambiente di runtime creato per eseguire dinamicamente codice che può essere pre-compilato, caricato da file esterno, scritto dall'utente e così via.

    Puoi trovare qualche spunto utile in questo articolo, o cercando in generale materiale su CodeDOM, DLR (Dynamic Language Runtime) e Reflection.Emit.

    Ciao! :)

  • Ma non vuole sapere come caricare un libreria dinamicamente, vorrà fare un parser su un'input di una riga dell'utente, senza però spenderci i mesi che servono a stendere specifiche e implementarle

  • Come suggerito da Alka puoi utilizzare CodeDom per scrivere codice c#(o vb.net) partendo da scelte dell'utente, https://learn.microsoft.com/it-it/dotnet/framework/reflection-and-codedom/using-the-codedom

  • 22/12/2022 - Weierstrass ha scritto:


    Ma non vuole sapere come caricare un libreria dinamicamente, vorrà fare un parser su un'input di una riga dell'utente, senza però spenderci i mesi che servono a stendere specifiche e implementarle

    Vuole sapere come eseguire una istruzione if() di C# che non faccia parte del suo programma, bensì digitata dall'utente in qualche casella di testo o comunque proveniente da qualcosa di esterno.

    Gli strumenti e le soluzioni tecniche ci sono, io stesso ne ho fatto uso, e la difficoltà implementativa dipende ovviamente da come si impostano le cose, ovvero “se l'utente deve scrivere un if(), i valori su cui si basa dovranno essere passati in qualche modo all'ambiente di runtime”, e come ho scritto, questo richiede una certa dimestichezza, ma non posso essere io a dire all'utente che non potrà mai farcela. :)

    Oltre alle soluzioni proposte, ci sono tante altre strade più immediate e comode per ottenere il risultato: ad esempio, io ho adottato con molta soddisfazione Flee, una libreria per la valutazione dinamica di espressioni basate su valori “iniettati” all'interno sottoforma di variabili.

    La domanda è posta in modo generico, altrettanto lo sono le risposte: le finalità sono chiare, dove e cosa cercare è già stato detto, a questo punto è l'autore della discussione a doversi cimentare con lo studio e con l'implementazione di quello che serve.

    Ciao! :)

  • Ciao, anch'io la penso come Oregon: non ha senso pensare ad un codice che si modifica a runtime. Fai piuttosto un'analisi più attenta e cambia il tipo di approccio al problema. Non posso credere che scrivere "300 if()" sia il modo giusto.

    Non è possibile modificare il codice compilato, e comunque, anche tanti anni fa quando programmavamo in assembler, era un'usanza sbagliata, che creava non pochi problemi con cache, multitasking, ecc… e in ogni caso, il codice che si automodifica verrebbe visto come virus, e bloccato dall'antivirus.

    Ciononostante, in C#, hai la possibilità di scrivere un codice sorgente (ovviamente dentro un file di testo), e poi invocare il compilatore dal tuo programma, per compilarlo al volo ed eseguirlo, magari, con un metodo tipo Process.Start.

    Non so se, nel tuo caso, ti ritorna utile:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.IO;
    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp;
    using Microsoft.CodeAnalysis.Emit;
    
    namespace Compilazione
    {
        class Program
        {
            static void Main(string[] args)
            {                        
                string nomeProgetto = "NumeriPrimi"; //nome che si vuole assegnare all'assembly
                string percorsoFile = @"D:\Programmi Compilati\Program.cs";  //posizione del file sorgente
    
                string code = File.ReadAllText(percorsoFile);            
                SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
                SyntaxTree[] sourceTrees = { tree };            
                
                MetadataReference[] references =
                {                
                    MetadataReference.CreateFromFile(typeof(System.Object).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(System.Linq.Enumerable).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(System.Numerics.BigInteger).Assembly.Location) //riferimento di esempio                               
                };
    
                CSharpCompilation compilation = CSharpCompilation.Create(nomeProgetto, sourceTrees, references, new CSharpCompilationOptions(OutputKind.ConsoleApplication));
                using (var ms = new MemoryStream())
                {
                    EmitResult result = compilation.Emit(ms);
                    if (!result.Success)
                    {
                        IEnumerable<Diagnostic> failures = result.Diagnostics.Where(Diagnostic =>
                            Diagnostic.IsWarningAsError ||
                            Diagnostic.Severity == DiagnosticSeverity.Error);
    
                        foreach (Diagnostic diagnostic in failures)
                        {
                            Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                        }                                                                    
                    }                    
                    else
                    {                                        
                        using (var file = File.Create($"{Path.GetDirectoryName(percorsoFile)}\\{compilation.AssemblyName}.exe"))
                            ms.WriteTo(file);
                        Console.WriteLine("Esito compilazione: success");
                    }                    
                }            
            }
    
        }
                         
    }
    
Devi accedere o registrarti per scrivere nel forum
19 risposte