Announcement

Collapse
No announcement yet.

command line output

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Chris Holbrook
    replied
    Originally posted by Fred Harris View Post
    ...and here's a c program I got working before I got it working in PowerBASIC (compiles with gcc. I used the Bloodshed IDE & dev suite from Sourceforge. Got mad at MS couple years back and won't use their stuff anymore).
    Fred, thanks for that example. I'm using Bloodshed too, and have just downloaded gcc - your code compiled & ran 100%. Also fed up with M$ but in this world that's a bit like objecting to breathing oxygen!

    What I'm after is to be able to run a single executable either as a GUI (if called without parameters) or as a command line exe from a batch file or a script. If run as a GUI, the calling shell does not need to wait for me. If called from a BAT or script, then the calling shell has to wait & receive my STDOUT and STDERR.

    Leave a comment:


  • Fred Harris
    replied
    Here's two links from where I was working on this stuff last fall Chris...

    http://www.powerbasic.com/support/pb...ad.php?t=35026

    http://www.powerbasic.com/support/pb...ad.php?t=34989

    ...and here's a c program I got working before I got it working in PowerBASIC
    (compiles with gcc. I used the Bloodshed IDE & dev suite from Sourceforge. Got mad at MS couple years back and won't use their stuff anymore).
    Code:
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>          //contains equate _O_TEXT
    #include <io.h>             //contains declare for _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
    #define  IDC_BUTTON  1500
    //extern int iArr[];
    
    //_CRTIMP int __cdecl _open_osfhandle(long, int);
    //long CDecl Lib "msvcrt.dll" _open_osfhandle(Long hHandle, Long iType)
    
    typedef struct    WindowsEventArguments               //Package Window Procedure Parameters into structure
    {
     HWND             hWnd;                               //Handle of Window
     WPARAM           wParam;                             //Window Parameter
     LPARAM           lParam;                             //Long Parameter
     HINSTANCE        hIns;                               //Instance Handle (Resolves To Process Address)
    }WndEventArgs, *lpWndEventArgs;
    
    
    long fnWndProc_OnCreate(lpWndEventArgs Wea)           //Called One Time During Window Creatiion
    {
     HWND hButton;
    	
     Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;  
     hButton=CreateWindow("button","Execute",WS_CHILD|WS_VISIBLE,70,70,141,30,Wea->hWnd,(HMENU)IDC_BUTTON,Wea->hIns,0);
     return 0;                                             
    }
    
    
    long fnWndProc_OnCommand(lpWndEventArgs Wea)
    {
     unsigned int i;
     int hCrt;
     FILE *hf;
     
     if(LOWORD(Wea->wParam)==IDC_BUTTON)
     {
        AllocConsole();
        hCrt=_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
        hf = _fdopen( hCrt, "w" );
        *stdout = *hf;
        i = setvbuf( stdout, NULL, _IONBF, 0 );
        printf("My Name Is Fred!\n");
    	MessageBox(Wea->hWnd,"Hopefully, You See A Console?","See A Console?",MB_ICONINFORMATION);
     }
    
     return 0;
    }
    
    
    long fnWndProc_OnClose(lpWndEventArgs Wea)            //This function handles the WM_CLOSE message
    {                                                     //sent when the 'x' button is clicked.
     if(MessageBox(Wea->hWnd,"Do You Wish To Exit This App?","Exit Check?",MB_YESNO)==IDYES)
     {
        DestroyWindow(Wea->hWnd);
        PostQuitMessage(WM_QUIT);
     }
    
     return 0;
    }
    
    
    long __stdcall fnWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) //This is the all important Window
    {                                                                        //Procedure.  Note that in WinMain()
     WndEventArgs wea;                                                       //the WNDCLASSEX variable wc has a
                                                                             //field lpfnWndProc.  This is pro- 
     switch (msg)                                                            //nounced long pointer to Window
     {                                                                       //Procedure.  Below you can see where
      case WM_CREATE:                                                        //this variable was set to the
        wea.hWnd=hwnd, wea.wParam=wParam, wea.lParam=lParam;                 //address of this function.  All
        return fnWndProc_OnCreate(&wea);                                     //messages destined for this program 
      case WM_COMMAND:                                                       //Windows  will package up into a 
        wea.hWnd=hwnd, wea.wParam=wParam, wea.lParam=lParam;                 //message packet consisting of the four
        return fnWndProc_OnCommand(&wea);                                    //parameters to this function and
      case WM_CLOSE:                                                         //and it will come blowing through
        wea.hWnd=hwnd, wea.wParam=wParam, wea.lParam=lParam;                 //here at blinding speed.
        return fnWndProc_OnClose(&wea);                                      
     }                                                                       
                                                                             
     return DefWindowProc(hwnd,msg,wParam,lParam);                           
    }
    
    
    int __stdcall WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR lpszArgument,int iShow)
    {                                  //The program starts in WinMain().  The WNDCLASSEX structure variable 
     char szClassName[]="Form1";       //wc is filled out with general characteristics of a window.  Then
     WNDCLASSEX wc;                    //the class is RegisteredClassEx()'ed.  Directly after that a 
     MSG messages;                     //CreateWindow() call instantiates an instance of the class.  Then
     HWND hWnd;                        //the program drops into a message processing loop in which any messages
                                       //destined for this program are DispatchMessage()'ed to the fnWndProc().
     wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
     wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_DBLCLKS;
     wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
     wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
     wc.hbrBackground=(HBRUSH)COLOR_BACKGROUND;   wc.cbWndExtra=0;
     wc.lpszMenuName=NULL;                        wc.cbClsExtra=0; 
     RegisterClassEx(&wc);
     hWnd=CreateWindow(szClassName,"Form1",WS_OVERLAPPEDWINDOW,200,100,300,250,HWND_DESKTOP,0,hIns,0);
     ShowWindow(hWnd,iShow);
     while(GetMessage(&messages,NULL,0,0))
     {
      TranslateMessage(&messages);
      DispatchMessage(&messages);
     }
    
     return messages.wParam;
    }

    Leave a comment:


  • Chris Holbrook
    replied
    more insights: http://blog.didierstevens.com/2008/0...st-gui-vs-cui/

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    Nope, never tried it myself, so I very much look forward to your results.
    I appear to have a serpent by the tail. http://support.microsoft.com/kb/190351 is also worth looking at, and there is a reference to it (use Q190351 as a search term) in two threads on this forum, both full of relevant stuff which I am gently absorbing. MCM I suspect you have been this way before!

    Trying to compile C examples, my current C compiler (MinGW) seems to hate them all, downloaded M$ Visual C++ Express Edition which looks pretty but needs (I suspect) a day's familiarisation. Who ever heard of a compiler without a COMPILE button?

    Leave a comment:


  • Michael Mattias
    replied
    OK but that creates a new console, the problem is getting the output into the "parent" console.
    I "think" you might be able to handle that via redirection... http://technet.microsoft.com/en-us/l.../bb490982.aspx ... by using the 'duplicate handle' options therein.

    Nope, never tried it myself, so I very much look forward to your results.

    Leave a comment:


  • Fred Harris
    replied
    Here's an example of opening a console window from a GUI process and using C's printf to output text. I know this is posted here someplace or other but I never put it in source code. It involves some of the same issues I believe as Michael was alluding to.

    Code:
    'Program demonstrates how to restore standard output handle in C Runtime Library
    'which is zeroed out by initialization of GUI process.
    #Compile Exe
    #Include "Win32api.inc"           'Translation of Windows.h for PowerBASIC
    %IDC_BUTTON1 = 1250               'ctrl id of button
    %O_TEXT      = &H4000             'from Fcntl.h
    
    Type FILE      'From stdio.h      'When a GUI application is started the three standard OS handles
      pChar        As Asciiz Ptr      'STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all
      cnt          As Long            'zeroed out by the console initialization routines.  These three
      pBase        As Asciiz Ptr      'handles are replaced by valid values when a GUI application calls
      flag         As Long            'AllocConsole(). Therefore, once this is done, calling GetStdHandle()
      fil          As Long            'will always return valid handle values. The problem is that the
      charbuf      As Long            'CRT has already completed initialization before an application gets
      bufsize      As Long            'a chance to call AllocConsole(); the three low I/O handles 0, 1,
      TmpFileName  As Asciiz Ptr      'and 2 have already been set up to use the original zeroed out OS
    End Type                          'handles, so all CRT I/O is sent to invalid OS handles and CRT output
                                      'does not appear in the console.
    
    Declare Function GetConsoleWindow Lib "Kernel32.dll" Alias "GetConsoleWindow" () As Dword
    
    
    Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
    ( _
      szFmtStr As Asciiz _
      [, _
         Byval lpVar1 As Any, _
         Byval lpVar2 As Any, _
         Byval lpVar3 As Any, _
         Byval lpVar4 As Any _
      ] _
    ) As Long
    
    
    Declare Function Open_OSFileHandle CDecl Lib "msvcrt.dll" Alias "_open_osfhandle" _  'from IO.h
    ( _
      Byval hHandle As Long, _
      Byval iType   As Long _
    ) As Long
    
    
    Declare Function FDOpen CDecl Lib "msvcrt.dll" Alias "_fdopen" _   'from stdio.h
    ( _
      Byval hHandle As Long, _
      ByRef pszStr As Asciiz _
    ) As Dword
    
    
    Function WndProc(Byval hWnd As Long,Byval wMsg As Long,Byval wParam As Long,Byval lParam As Long) As Long
      Select Case wMsg
        Case %WM_CREATE
          Local hButton As Dword
          Local hIns As Dword
          hIns=GetModuleHandle(Byval 0)
          hButton=CreateWindow("button","Show Console!",%WS_CHILD Or %WS_VISIBLE,110,65,200,25,hWnd,%IDC_BUTTON1,hIns,Byval 0)
          WndProc=0
          Exit Function
        Case %WM_COMMAND
          If Lowrd(wParam)=%IDC_BUTTON1 And HiWrd(wParam)=%BN_CLICKED Then
             Local hStdOutput As Dword              'Standart Output Handle
             Local hf,ptrFile As FILE Ptr           'FILE *
             Local hDll,hCrt,dwWeight As Dword
             Local hSysMenu As Dword
             Register i As Long
             hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
             If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
                ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
                Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
                hSysMenu=GetSystemMenu(GetConsoleWindow(),Byval 0)   'must be reset with valid operating system handles if
                Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
                hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
                hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
                @ptrFile[1][email protected]                     '@[email protected] printf output using CRT in PowerBASIC!
                dwWeight=210
                For i=1 To 200                     '
                  printf("%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!"+$Cr+$Lf,i,dwWeight)
                Next i
                Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
             End If
          End If
          WndProc=0
          Exit Function
        Case %WM_DESTROY
          Call PostQuitMessage(0)
          WndProc=0
          Exit Function
      End Select
    
      WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
    End Function
    
    Function WinMain(Byval hIns As Long, Byval hPrev As Long, Byval lpCL As Asciiz Ptr, Byval iShow As Long) As Long
      Local szBuffer As Asciiz * 64
      Local wc As WNDCLASSEX
      Local Msg As tagMsg
      Local hWnd As Dword
    
      szBuffer="Console_Output"                           : wc.lpszClAssName=Varptr(szBuffer)
      wc.lpfnWndProc=Codeptr(WndProc)                     : wc.cbSize=Sizeof(wc)
      wc.style=%CS_HREDRAW Or %CS_VREDRAW                 : wc.hInstance=hIns
      wc.cbClsExtra=0                                     : wc.cbWndExtra=0
      wc.hIcon=LoadIcon(%NULL, Byval %IDI_APPLICATION)    : wc.hCursor=LoadCursor(%NULL, Byval %IDC_ARROW)
      wc.hbrBackground=%COLOR_BTNFACE+1                   : wc.lpszMenuName=%NULL
      Call RegisterClAssEx(wc)
      szBuffer="GUI Console Output With C Runtime Library From PowerBASIC!"
      hWnd=CreateWindow("Console_Output",szBuffer,%WS_OVERLAPPEDWINDOW,500,550,440,200,0,0,hIns,Byval 0)
      Call ShowWindow(hWnd,iShow)
      Call UpdateWindow(hWnd)
      While GetMessage(Msg,%NULL,0,0)
        TranslateMessage Msg
        DispatchMessage Msg
      Wend
    
      Function=msg.wParam
    End Function

    Leave a comment:


  • Chris Holbrook
    replied
    Originally posted by Michael Mattias View Post
    "kind of" solves the "output" side of things
    OK but that creates a new console, the problem is getting the output into the "parent" console.

    Leave a comment:


  • Michael Mattias
    replied
    Well, STDOUT for PB.Windows (Simple STDOUT for PB/DLL and PB/Win 2-13-04) "kind of" solves the "output" side of things, except for the documented bug in Windows/XP I recently posted here:

    http://www.powerbasic.com/support/pb...ad.php?t=37183

    My current workaround (GetConsoleWindow()) will only work on Window/XP+, and of course does not allow for the possibility that the STDOUT was correctly redirected to another handle by the parent process. I was going to put the code needed for that into that STDOUT code Real Soon Now but have not gotten to it.

    MCM
    Last edited by Michael Mattias; 5 May 2008, 01:52 PM.

    Leave a comment:


  • Chris Holbrook
    started a topic command line output

    command line output

    It would be useful if my application could behave both as an interactive and a command line program. For this, I need to be able to send output to the command line, but that command line is (I assume) the parent application's console. For example, if the application is called from a "Command Prompt" shell with a parameter, let it echo the parameter to the shell, and if called without a parameter, let it open a window. How would I do that?
Working...
X