Prototype de Shell Terminal

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Prototype de Shell Terminal

Message par JohnJohnsonSHERMAN »

Voici un de mes derniers projets : un shell intérpréteur de commandes en mode console.
Il suffit d'entrer une commande et le shell l'exécute. Pour l'instant le choix des commandes est encore trés restreint, mais je compte en ajouter par la suite.
Les commandes de bases sont :
  • cmd : ouvre l'invite de commandes Windows (cmd.exe) dans le terminal
  • help : Affiche l'aide
  • clear : Devrait effacer la console avec ClearConsole(), mais ne fait rien
  • date : Affiche la date
  • system : Librairie System
    • name : Donne le nom de l'ordinateur
    • serial : Donne le numéro de série de l'ordinateur
    • username : Renvoie le nom de l'utilisateur connecté
    • cpu : Renvoie le modéle du CPU installé
    • help : Aide de la lib System
  • dir : Librairie Directory
    • home : Affiche le répertoire de l'utilisateur
    • current : Affiche le répertoire courant (équivalent à pwd sous Linux)
    • temporary : Affiche le rép. temporaire
    • set : Change le répertoire de travail (celui du prompt). Il faut préciser entre " le nouveau répertoire : dir.set "nouveau répertoire"
    • help : Affiche l'aide de la lib direrctory
Les commandes seront organisées par librairies, et entrées à la "mode POO". Oui je sais il y en a qui n'aiment pas ca, mais c'est juste pour simplifier l'écriture de mon code. Exemple : system.name renverra le résultat de la fonction PB ComputerName de la librairie System. Exit les trucs du genre system.computer.name.get à la facon du java, ce qui est pour moi imbuvable :P
J'ai ajouté de l'aide sur les commandes en entrant 'help' ou le nom de la lib + '.help'.
Pour l'instant, il n'y a que deux librairies : system et dir (gestion des répertoires, création, suppression, répertoires courants, récursivité).
J'ajouterai par la suite d'autres librairies comme 'file' pour gérer et ouvrir des fichiers, 'date' pour gérer les heures, 'process' pour les processus (pid, liste des process, kill de process), et pourquoi pas 'web' pour ce qui est de l'internet (dl de fichiers, connections, ping...), voire d'autres encore...

A savoir que ce n'est pas un simple wrapper de fonctions pb, c'est plus pour moi un outil de remplacement à cmd que je trouve un peu chiant. Seules les bases étant posées pour l'instant, il n'y a presque rien a voir :mrgreen:

Le code :

Code : Tout sélectionner

prompt$ = "SH_SHELL 1.0 :: "+GetCurrentDirectory()+">"
help$ = ~"Sherman Shell Terminal Help page\nThis is the help of the ShermanShell Terminal.\nUse one of the following commands on the terminal when the prompt is visible on the terminal.\nCommands are :\nexit : Exits the terminal.\nclear : Clears the terminal's screen.\ncmd : Run the Windows's cmd.exe terminal.\nhelp : Displays this page.\n"
help_System$ = ~"System Lib Help\nThis page refers to the help of the System Library Commands in the Sherman Shell Terminal.\nCommands : \nsystem.name\t: returns the name of the current computer.\nsystem.cpu\t: Returns the name of the current used CPU.\nsystem.username : returns the name of the user currently logged on.\nsystem.serial\t: Returns the serial number of this computer.\nsystem.help\t: Displays this page.\n"
help_Directory$= ~"Directory lib Help\nThis page refers to the help of the Directory (dir) library\ndir.home\t:Returns the home directory.\ndir.current\t:Returns the current working directory. Same as 'pwd'.\ndir.temporary\t:Returns the temporary directory.\ndir.set\t:Changes the working directory to the new one (must be typed with \"  before and after).\ndir.help\t:Displays this page.\n"
OpenConsole("Sherman Shell Terminal (SHSHELL)")
ConsoleColor(0,7)
PrintN("          (c)ShermanSoftware - Sherman Command-line Terminal           ")
ConsoleColor(7,0)
PrintN("Console initializated. Command-line is now enabled.")


Repeat
  
  Print(prompt$)
  re$ = Input()
  command$ = StringField(re$,1," ")
  param$= StringField(re$,2," ")
  lib$ = StringField(command$,1,".")
  Select lib$
    Case "cmd"
      ExternalProg = RunProgram("cmd.exe","-help","",#PB_Program_Hide | #PB_Program_Open | #PB_Program_Read | #PB_Program_UTF8)
      If ExternalProg
        While ProgramRunning(ExternalProg)
          If AvailableProgramOutput(ExternalProg)
            PrintN(ReadProgramString(ExternalProg))
          EndIf
        Wend
        PrintN("Execution finished")
      Else
        PrintN("Unable to run cmd.exe.")
      EndIf
    Case "exit"
      End
    Case "clear"
      ClearConsole()
    Case "-help"
      PrintN(help$)
    Case "help"
      PrintN(help$)
    Case "-h"
      PrintN(help$)
    Case "date"
      PrintN(FormatDate("%dd/%mm/%yyyy, %hh:%ii:%ss",Date()))
    Case "system"
      Select StringField(re$,2,".")
        Case "name"
          PrintN(ComputerName())
        Case "serial"
          PrintN(ComputerSerialNumber())
        Case "username"
          PrintN(UserName())
        Case "cpu"
          PrintN(CPUName())
        Case "help"
          PrintN(help_System$)
        Default 
          PrintN("This is not a command of the 'system' interface. Please refer to the related help by typing 'system.help' to see the System commands.")
      EndSelect
    Case "pwd"
      PrintN(GetCurrentDirectory())
    Case "dir"
      Select StringField(command$,2,".")
        Case "temporary"
          PrintN(GetTemporaryDirectory())
        Case "current"
          PrintN(GetCurrentDirectory())
        Case "home"
          PrintN(GetHomeDirectory())
        Case "help"
          PrintN(help_Directory$)
        Case "set"
          currentDir$ = StringField(param$,2,~"\"")
          If SetCurrentDirectory(currentDir$)
            PrintN("Working directory changed to '"+currentDir$+"'.")
            prompt$ = "SH_SHELL 1.0 :: "+GetCurrentDirectory()+">"
          Else
            PrintN("Unable to change the working directory to '"+currentDir$+"'. Make sure you entered a real directory name.")
          EndIf
          
        Default
          PrintN("This is not a command of the 'dir' (Directory) interface. To see the list of available commands, please type 'dir.help'.")
      EndSelect
      
    
    Default
      PrintN("'"+re$ + "' is not a command currently available in this terminal. Enter -h or -help for more help about the Sherman Shell Terminal.")
      
  EndSelect
ForEver
Bugs : la redirection de Cmd ne se fait ni en unicode, ni en UTF-8, ni en ASCII, mais dans une Codepage de Microsoft. Donc les caractéres spéciaux ne s'affichent pas.
Le prompt de cmd ne se réaffiche pas tout seul aprés une fonction de cmd.
L'autocomplétion avec Tab ne marche pas non plus.
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Prototype de Shell Terminal

Message par PAPIPP »

Bonjour JohnJohnsonSHERMAN

EN 2009 j'avais réalisé un prg PUNCH d'aide à MSDOS

Pour obtenir des résultats lisible dans window il faut utiliser OemToChar_(@text$, @text$), pour convertir ASCII (MSDOS) en ANSI

http://msdn.microsoft.com/en-us/library ... S.85).aspx

En ASCII (contrairement donc au mode UNICODE) pas besoin d'allouer une variable pour le résultat,
il suffit de mettre le même pointeur qu'en entrée : OemToChar_(@text$, @text$),
un remplacement octet par octet est effectué dans la chaine passée en premier argument.

Code : Tout sélectionner

;*****************************************************************************
;*
;* PurePunch Contest #3
;*
;* Name     : "Help MSDOS Normal" Aide Msdos Double cliquez sur une ligne
;* Author   : PAPIPP
;* Category : UTIL
;* Date     : 15 / 07 / 09
;*
;*****************************************************************************
;----0---_____1____----2-----_____3____-----4----_____5____-----6----_____7____-
;2345678901234567890123456789012345678901234567890123456789012345678901234567890
Ci$="CMD COMP DATE LABEL MORE PAUSE SORT TIME"
Macro M:Macro : EndMacro:M AGI:AddGadgetItem:EndMacro:#W0=0:#L0=0:#L1=1:#G=2
M RPS :ReadProgramString:EndMacro
:Procedure OW0():
If OpenWindow(#W0, 0, 0, 800, 600, "Dbl Clic")
:ListViewGadget(#L0, 0, 0, 800, 300)
:EditorGadget(#L1, 0, 300, 800, 300,#PB_Editor_ReadOnly)
GadgetToolTip(#L0, "Double Cliquez sur une des ligne pour une aide")
:EndIf
EndProcedure
:Procedure AFCH(Gd,Cm$)
prg=RunProgram("cmd"," /C "+CM$,"",30)
As$=Space($FFFF):ClearGadgetItems(Gd)
:If prg:As$=RPS(prg)
OemToChar_(@as$,@as$)
:AGI(gd,-1,Cm$+" :"+As$)
While ProgramRunning(prg)
:As$ =RPS(prg)
:OemToChar_(@as$,@as$)
;
; Petite remarque sur a fonction OemToChar() :
; [url]http://msdn.microsoft.com/en-us/library/ms647493(VS.85).aspx[/url]
; En ASCII (contrairement donc au mode UNICODE) pas besoin d'allouer une variable pour le résultat,
; il suffit de mettre le même pointeur qu'en entrée : OemToChar_(@text$, @text$),
;  un remplacement octet par octet est effectué dans la chaine passée en premier argument.

:AGI(Gd,-1, As$)
Wend
:EndIf
:EndProcedure
:OW0():Font1 = LoadFont(#PB_Any, "Courier New",8)
SetGadgetFont(#L0, FontID(Font1)):SetGadgetFont(#L1, FontID(Font1))
AFCH(#L0,"Help ")
:Repeat: WWE = WaitWindowEvent()
:Select WWE
:Case #PB_Event_Gadget
:EG = EventGadget():ET = EventType()
:If EG = #L0
 : EL.l=GetGadgetState(#L0)
 :EL$= GetGadgetItemText(#L0, El):Pos= FindString(el$, " ", 1):
 :CMD$=Mid(el$,1,pos-1)
; :If ET = #PB_EventType_LeftClick ;= 0
   If ET=0
    cmd$="Help "+CMD$
   :AFCH(#L1, CMD$)
   EndIf
: If ET=2
     
   If FindString(Ci$,cmd$, 0)=0
     rs=MessageRequester ("EXECUTION DE "+CMD$,"Voulez vous exécutez cette Cmd", #PB_MessageRequester_YesNo )
     If rs=#PB_MessageRequester_Yes
      Texte$ = InputRequester("EXECUTION "+cmd$ , "Complétez la commande", cmd$+" ")
     ; Controler la commande pour éviter les conneries
      cmd$=texte$
     :AFCH(#L1, CMD$)
     EndIf
     Else
     MessageRequester(cmd$+" Interdite"," Cette cmd : "+ cmd$+" bloque le prg",#PB_MessageRequester_Ok)
    EndIf 
 :EndIf
:EndIf
:Case #PB_Event_CloseWindow
:EW = EventWindow()
:If EW = #W0:CloseWindow(#W0)
:Break
:EndIf
:EndSelect
ForEver
; **********************************

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Prototype de Shell Terminal

Message par JohnJohnsonSHERMAN »

Merci PAPIPP !
Mais du coup en Unicode, il faut utiliser un pointeur si j'ai bien lu?
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Répondre