C # é o principal problema

10

Este quebra-cabeça de programação é inspirado em outra pergunta que foi feita aqui ontem, mas que foi excluída pelo autor ...

O desafio:

Crie um binário executável (Windows .EXE ou Linux) usando o Visual C # (ou seu IDE favorito do C #) que imprime o seguinte texto na saída padrão:

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

... sem usar as 4 letras consecutivas PRINCIPAIS que aparecem em qualquer arquivo de origem!

Notas:

  • Se o seu código fonte contiver o texto remainder(por exemplo), ele conterá as 4 letras consecutivas MAIN, no entanto, se contiver mxainas 4 letras, não seria mais consecutivo, portanto, mxainseria permitido.
  • Você não tem permissão para executar nenhum programa, exceto o C # IDE, nem alterar as configurações do C # IDE para executar outros programas (mas os que normalmente seriam executados, como o compilador C #).

    Caso contrário, você poderia simplesmente dizer: "Eu escrevo um programa Pascal usando o C # IDE e invoco o compilador Pascal nas etapas de 'pré-compilação' do meu projeto C #".

    Isso seria muito simples.

  • Os usuários de um IDE que possam ser estendidos usando "plug-ins" (ou similares) ou que tenham editores de arquivos binários internos (editores hexadecimais) terão uma vantagem muito grande sobre os usuários de outros IDEs C #.

    Portanto, esses talentos também não devem ser usados.

  • É permitido o uso de outros editores não ASCII (como o editor da janela de diálogo)!
  • O usuário que faz a pergunta original proposta usando a barra invertida nos nomes das funções, assim: static void M\u0061in()Como essa resposta já foi lida por outros usuários, ela não será mais aceita!
  • Um usuário perguntou se seria permitido digitar simplesmente um arquivo .EXE no editor de código-fonte e salvar o arquivo como ".exe" em vez de ".cs". Resposta: Não duvido que isso seja possível porque os binários válidos do Windows e Linux contêm NUL bytes. No entanto, se você encontrar um binário válido que possa ser criado dessa maneira, terá uma solução válida.

O nome deste site é "Quebra - cabeças de programação e código de golfe" - este é um "Quebra-cabeça de programação", não "Código de golfe": o desafio é encontrar uma solução funcional para todos os outros usuários, não encontrar uma solução mais curta que todas as outras soluções.

Portanto, o primeiro post que descreve uma solução funcional vence !

Boa sorte!

A propósito: Eu tenho uma solução trabalhando no Visual C # Express 2010.

Martin Rosenau
fonte
2
O que me impede de usar meu C # IDE como um editor de texto (ou binário) para digitar diretamente um executável?
feersum
2
Qual resposta vence o desafio? A primeira resposta válida? Você deve especificar a condição vencedora #
James
Se o IDE contiver algum editor hexadecimal ou similar, isso NÃO será permitido. Se você conseguir usar o editor de texto ASCII para digitar um arquivo binário válido, isso será permitido. Observe que um arquivo binário válido contém bytes no intervalo de 0x00 a 0x1F!
Martin Rosenau
2
Eu acho que esse é um desafio interessante. "Escreva um programa C # sem main". No entanto, a maioria das regras trata de quais ferramentas / IDEs usar e banir determinadas abordagens. Eu adoraria ver mais quebra-cabeças de programação (em oposição ao código-golfe), mas este é subespecificado. Eu recomendo usar a sandbox na próxima vez.
James
4
... Considere a caixa de areia da próxima vez.
gato

Respostas:

5

Janela C # interativa

Abra a janela interativa do C # (Exibir> Outras janelas> C # interativo no Visual Studio 2015). Suponho que nem todos os IDEs terão isso.

Essa abordagem executa C # na janela interativa para criar um exe em C # que imprime a string desejada sem que o autor nunca tenha escrito main. Como bônus, o IL do exe também não contém main.

Execute o seguinte código na janela interativa

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");

Use Environmnent.CurrentDirectorypara ver onde o exe foi criado. Execute-o para observar a saída desejada.

insira a descrição da imagem aqui

IL resultante: insira a descrição da imagem aqui

leite
fonte
Na verdade, eu gosto mais deste, então do WPF, porque você não tem Main () na sua Assembléia.
Htde # 21/16
Sua solução é interessante. É o segundo, então você vencerá se os usuários me convencerem de que o primeiro post não é uma solução válida (por qualquer motivo).
Martin Rosenau 21/10
Se você me perguntar, não importa realmente qual postagem vence, pois ambas são do mesmo usuário.
Htde # 21/16
@ hstde - Desculpe, eu não vi isso. Obrigado.
Martin Rosenau
@ lek Você publicou duas soluções válidas (bem, alguns usuários têm dúvidas sobre a primeira) para ganhar. Parabéns.
Martin Rosenau
3

Aplicativo WPF

  1. Crie um novo aplicativo WPF. insira a descrição da imagem aqui

  2. Substitua todas as instâncias MainporMeow insira a descrição da imagem aqui

  3. Renomeie MainWindow.xamlpara MeowWindow.xaml. Isso será renomeado automaticamente MainWindow.xaml.cspara MeowWindow.xaml.cs.

insira a descrição da imagem aqui

  1. Nas propriedades do projeto, altere o Tipo de saída para Console Applicationpara que o console seja criado. insira a descrição da imagem aqui

  2. Adicione gravação de console para a sequência de saída desejada em seu MeowWindowconstrutor insira a descrição da imagem aqui

  3. Ctrl + Shift + F para confirmar que não há nenhum mainlugar no diretório de origem. insira a descrição da imagem aqui

  4. F5 / compilar e executar. insira a descrição da imagem aqui

Como funciona

Para aplicativos WPF, o Visual Studio gera obj\Debug\App.g.csqual contém o Mainmétodo O gerado Maincria uma instância do seu aplicativo WPF e o inicia.

leite
fonte
Solução interessante. Alguém que acha que essa não é uma solução válida? Se alguém achar que esta publicação não é válida, por favor publique um comentário. Caso contrário, declararei esta solução como a vencedora, porque foi obviamente a primeira publicada.
Martin Rosenau
@MartinRosenau Eu sinto que desde que você poderia decompor o aplicativo WPF e não haveria um método main que este é inválida, mais fortemente, porque o mesmo usuário postou outra resposta que não tem essa ambiguidade
Acabei de ver que as duas respostas foram postadas pelo mesmo usuário. Nesse caso, esse usuário vencerá de qualquer maneira.
Martin Rosenau
0

Apenas como referência

Minha idéia foi semelhante à segunda idéia do "leite":

Encontre uma maneira de permitir que o IDE execute o código e grave um executável no disco.

Mencionei explicitamente os binários do Windows e Linux, porque pensei em gravar o arquivo .EXE binário usando, System.IO.File.WriteAllBytes()para que não fosse necessariamente um arquivo .NET EXE.

Meu problema era que o VS Express 2010 parece não ter um console interativo, então tive que encontrar um substituto para isso - encontrei o seguinte:

Crie um projeto DLL com uma janela de diálogo e um controle personalizado; compile o projeto e adicione o controle personalizado à janela de diálogo. O editor da janela de diálogo chamará o código do controle personalizado - e nesse código você poderá gravar o arquivo .EXE no disco ...

Martin Rosenau
fonte