C # ist das Hauptproblem

10

Dieses Programmierpuzzle ist inspiriert von einer anderen Frage, die gestern hier gestellt wurde, aber vom Autor gelöscht wurde ...

Die Herausforderung:

Erstellen Sie eine ausführbare Binärdatei (Windows .EXE- oder Linux-Binärdatei) mit Visual C # (oder Ihrer bevorzugten C # -IDE), die den folgenden Text in die Standardausgabe druckt:

Main() is the main method of C# programs!

... ohne die 4 aufeinander folgenden Buchstaben MAIN zu verwenden, die in einer Quelldatei erscheinen!

Anmerkungen:

  • Wenn Ihr Quellcode den Text enthält remainder(zum Beispiel), enthält er die 4 aufeinanderfolgenden Buchstaben MAIN. Wenn er jedoch mxaindie 4 Buchstaben enthält, ist dies nicht mehr aufeinanderfolgend mxainzulässig.
  • Sie dürfen keine Programme außer der C # -IDE ausführen oder die Einstellungen der C # -IDE ändern, um andere Programme auszuführen (aber diejenigen, die normalerweise ausgeführt werden, wie z. B. den C # -Compiler).

    Ansonsten könnte man einfach sagen: "Ich schreibe ein Pascal-Programm mit der C # -IDE und rufe den Pascal-Compiler in den 'Pre-Build'-Schritten meines C # -Projekts auf."

    Das wäre zu einfach.

  • Benutzer einer IDE, die mithilfe von "Plug-Ins" (oder ähnlichem) erweitert werden können oder über integrierte Binärdatei-Editoren (Hex-Editoren) verfügen, hätten einen zu großen Vorteil gegenüber Benutzern anderer C # -IDEs.

    Daher sollten diese Merkmale auch nicht verwendet werden.

  • Die Verwendung der anderen Nicht-ASCII-Editoren (wie des Dialogfenster-Editors) ist ausdrücklich gestattet!
  • Der Benutzer, der die ursprüngliche Frage gestellt hat, schlug den Backslash in Funktionsnamen wie static void M\u0061in()folgt vor : Da diese Antwort bereits von anderen Benutzern gelesen wurde, wird sie nicht mehr akzeptiert!
  • Ein Benutzer fragte, ob es erlaubt sei, einfach eine EXE-Datei in den Quellcode-Editor einzugeben und die Datei als ".exe" anstelle von ".cs" zu speichern. Antwort: Ich bezweifle nicht, dass dies möglich ist, da sowohl gültige Windows- als auch Linux-Binärdateien NUL-Bytes enthalten. Wenn Sie jedoch eine gültige Binärdatei finden, die auf diese Weise erstellt werden kann, haben Sie eine gültige Lösung.

Der Name dieser Website lautet "Programming Puzzles & Code Golf" - dies ist ein "Programming Puzzle", nicht "Code Golf": Die Herausforderung besteht darin, vor allen anderen Benutzern eine funktionierende Lösung zu finden und keine kürzere Lösung als alle anderen zu finden Lösungen.

Daher gewinnt der erste Beitrag, der eine funktionierende Lösung beschreibt !

Viel Glück!

Übrigens: Ich habe eine Lösung, die unter Visual C # Express 2010 funktioniert.

Martin Rosenau
quelle
2
Was hindert mich daran, meine C # -IDE als Text- (oder Binär-) Editor zu verwenden, um eine ausführbare Datei direkt einzugeben?
Feersum
2
Welche Antwort gewinnt die Herausforderung? Die erste gültige Antwort? Sie sollten die Gewinnbedingung angeben
James
Wenn die IDE einen hexadezimalen Editor oder ähnliches enthält, ist dies NICHT zulässig. Wenn Sie es schaffen, mit dem ASCII-Texteditor eine gültige Binärdatei einzugeben, ist dies zulässig. Beachten Sie, dass eine gültige Binärdatei Bytes im Bereich von 0x00 bis 0x1F enthält!
Martin Rosenau
2
Ich denke, das ist insgesamt eine interessante Herausforderung. "Schreiben Sie ein C # -Programm ohne main". In den meisten Regeln geht es jedoch darum, welche Tools / IDEs verwendet werden sollen, und um bestimmte Ansätze zu verbieten. Ich würde gerne mehr Programmierpuzzles sehen (im Gegensatz zu Code-Golf), aber dieses ist nicht genau spezifiziert. Ich würde empfehlen, das nächste Mal die Sandbox zu verwenden .
James
4
... Betrachten Sie das nächste Mal den Sandkasten .
Katze

Antworten:

5

C # Interaktives Fenster

Öffnen Sie das interaktive C # -Fenster (Ansicht> Andere Fenster> C # Interaktiv in Visual Studio 2015). Ich nehme an, dass nicht alle IDEs dies haben werden.

Dieser Ansatz führt C # im interaktiven Fenster aus, um eine C # -Exe zu erstellen, die die gewünschte Zeichenfolge druckt, ohne dass der Autor jemals schreibt main. Als Bonus enthält die IL der Exe auch nicht main.

Führen Sie den folgenden Code im interaktiven Fenster aus

using System.Reflection;
using System.Reflection.Emit;
var appMeow = (dynamic)System.Type.GetType("System.AppDom" + "ain").GetProperty("CurrentDom" + "ain", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public).GetValue(null);
var asmName = new AssemblyName("MEOW");
var asmBuilder = appMeow.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var module = asmBuilder.DefineDynamicModule("MEOW", "MEOW.exe");
var typeBuilder = module.DefineType("Meow", TypeAttributes.Public);
var entryPoint = typeBuilder.DefineMethod("EntryPoint", MethodAttributes.Static | MethodAttributes.Public);
var il = entryPoint.GetILGenerator();
il.Emit(OpCodes.Ldstr, "Meow() is the meow method of C# programs!");
il.Emit(OpCodes.Ldstr, "eow");
il.Emit(OpCodes.Ldstr, "ain");
il.EmitCall(OpCodes.Call, typeof(string).GetMethod("Replace", new[] { typeof(string), typeof(string) }), null);
il.EmitCall(OpCodes.Call, typeof(Console).GetMethod("Write", new[] { typeof(string) }), null);
il.Emit(OpCodes.Ret);
var type = typeBuilder.CreateType();
asmBuilder.SetEntryPoint(type.GetMethods()[0]);
asmBuilder.Save("MEOW.exe");

Verwenden Sie Environmnent.CurrentDirectorydiese Option, um zu sehen, wo die Exe erstellt wurde. Führen Sie es aus, um die gewünschte Ausgabe zu beobachten.

Geben Sie hier die Bildbeschreibung ein

Resultierende IL: Geben Sie hier die Bildbeschreibung ein

Milch
quelle
Ich mag dieses tatsächlich besser als das WPF, weil Sie tatsächlich überhaupt kein Main () in Ihrer Assembly haben.
hstde
Ihre Lösung ist interessant. Es ist das zweite, also werden Sie gewinnen, wenn die Benutzer mich davon überzeugen sollten, dass der erste Beitrag keine gültige Lösung ist (aus welchem ​​Grund auch immer).
Martin Rosenau
Wenn Sie mich fragen, spielt es keine Rolle, welcher Beitrag gewinnt, da beide vom selben Benutzer stammen.
hstde
@hstde - Entschuldigung, ich habe das nicht gesehen. Vielen Dank.
Martin Rosenau
@milk Sie haben zwei gültige Lösungen veröffentlicht (einige Benutzer haben Zweifel an der ersten), sodass Sie gewinnen. Herzliche Glückwünsche.
Martin Rosenau
3

WPF-Anwendung

  1. Erstellen Sie eine neue WPF-Anwendung. Geben Sie hier die Bildbeschreibung ein

  2. Ersetzen Sie alle Instanzen von MaindurchMeow Geben Sie hier die Bildbeschreibung ein

  3. Umbenennen MainWindow.xamlin MeowWindow.xaml. Dies wird automatisch umbenannt MainWindow.xaml.cszu MeowWindow.xaml.cs.

Geben Sie hier die Bildbeschreibung ein

  1. Ändern Sie in den Projekteigenschaften den Ausgabetyp in, Console Applicationdamit die Konsole erstellt wird. Geben Sie hier die Bildbeschreibung ein

  2. Fügen Sie in Ihrem MeowWindowKonstruktor Konsolenschreiben für die gewünschte Ausgabezeichenfolge hinzuGeben Sie hier die Bildbeschreibung ein

  3. Strg + Umschalt + F, um zu bestätigen, dass sich mainim Quellverzeichnis keine Stelle befindet. Geben Sie hier die Bildbeschreibung ein

  4. F5 / kompilieren und ausführen. Geben Sie hier die Bildbeschreibung ein

Wie es funktioniert

Für WPF-Anwendungen generiert Visual Studio, obj\Debug\App.g.csdas die MainMethode enthält . Das generierte Mainerstellt eine Instanz Ihrer WPF-App und startet sie.

Milch
quelle
Interessante Lösung. Wer glaubt, dass dies keine gültige Lösung ist? Wenn jemand der Meinung ist, dass dieser Beitrag nicht gültig ist, schreibe bitte einen Kommentar. Andernfalls werde ich diese Lösung zur Gewinnerin erklären, da sie offensichtlich die erste war, die veröffentlicht wurde.
Martin Rosenau
@ MartinRosenau Ich glaube, da Sie die wpf-App dekompilieren könnten und es eine Hauptmethode geben würde, ist dies ungültig, stärker, weil derselbe Benutzer eine andere Antwort gepostet hat, die diese Mehrdeutigkeit nicht aufweist
Ich habe gerade gesehen, dass beide Antworten vom selben Benutzer gepostet wurden. In diesem Fall gewinnt dieser Benutzer trotzdem.
Martin Rosenau
0

Nur als Referenz

Meine Idee ähnelte der zweiten Idee von "Milch":

Finden Sie eine Möglichkeit, die IDE Code ausführen zu lassen und eine ausführbare Datei auf die Festplatte zu schreiben.

Ich habe Windows- und Linux-Binärdateien ausdrücklich erwähnt, weil ich darüber nachgedacht habe, die binäre System.IO.File.WriteAllBytes()EXE-Datei mit zu schreiben, damit es sich nicht unbedingt um eine .NET EXE-Datei handelt.

Mein Problem war, dass VS Express 2010 keine interaktive Konsole zu haben scheint, daher musste ich einen Ersatz dafür finden - ich fand Folgendes:

Erstellen Sie ein DLL-Projekt mit einem Dialogfenster und einem benutzerdefinierten Steuerelement. Kompilieren Sie das Projekt und fügen Sie das benutzerdefinierte Steuerelement zum Dialogfenster hinzu. Der Dialogfenster-Editor ruft dann den Code des benutzerdefinierten Steuerelements auf - und in diesem Code können Sie die EXE-Datei auf die Festplatte schreiben ...

Martin Rosenau
quelle