Annotation of q_a/samples/startp/startp.c, revision 1.1.1.3

1.1.1.3 ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
1.1       root       12: /********************************************************************
                     13: * This program demonstrates various CreateProcess parameters,       *
                     14: * including starting processes in a given priority class. This is   *
                     15: * very similar to the "start" command but with added functionality. *
                     16: *                                                                   *
                     17: * This program demonstrates the use of the following Win32 APIs:    *
                     18: *   CreateProcess, TerminateProcess.                                *
                     19: *                                                                   *
                     20: * This program also uses the following Win32 APIs:                  *
                     21: *   WaitForSingleObject GetLastError.                               *
                     22: *                                                                   *
                     23: * Execution instructions:                                           *
                     24: *   see the help() function or run the program without any          *
                     25: *   parameters to see detailed execution info.                      *
                     26: *                                                                   *
1.1.1.3 ! root       27: * Possible enhancements:                                            *
1.1       root       28: *   Handle cmd.exe internal commands                                *
                     29: ********************************************************************/
                     30: 
1.1.1.3 ! root       31: #include <windows.h>
1.1       root       32: #include <string.h>
                     33: #include <stdio.h>
                     34: #include <stdlib.h>
                     35: 
                     36: /* Standard error macro for reporting API errors */
1.1.1.3 ! root       37: #define PERR(bSuccess, api) {if (!(bSuccess)) printf("%s: Error %d from %s \
        !            38:     on line %d\n", __FILE__, GetLastError(), api, __LINE__);}
1.1       root       39: 
                     40: void help()
                     41: {
                     42:   puts("Starts a specified program, batch, or command file.");
1.1.1.3 ! root       43:   puts("STARTP [/Ttitle] [/Dpath] [/l] [/h] [/r] [/min] [/max] [/w]");
        !            44:   puts("       [/c] [/b] [program] [parameters]");
1.1       root       45:   puts("\n    title       Title to display in window title bar. Quote the");
                     46:   puts("                entire paramter to include spaces in the title,");
                     47:   puts("                i.e. startp \"/Ttest job\"");
                     48:   puts("    path        Starting directory");
                     49:   puts("    l           Set default to low priority");
1.1.1.3 ! root       50:   puts("    h           Set default to high priority");
        !            51:   puts("    r           Set default to realtime priority");
1.1       root       52:   puts("    min         Start window minimized");
                     53:   puts("    max         Start window maximized");
                     54:   puts("    w           Wait for started process to end before returning");
                     55:   puts("                control to the command processor. This option starts");
                     56:   puts("                the process synchronously");
                     57:   puts("    c           Use current console instead of creating a new console");
1.1.1.3 ! root       58:   puts("    b           Start detached with no console at all");
1.1       root       59:   puts("    program     A batch file or program to run as either a GUI");
                     60:   puts("                application or a console application");
                     61:   puts("    parameters  These are the parameters passed to the program");
                     62:   puts("\nNote that the priority parameters may have no effect if the program");
                     63:   puts("changes its own priority.");
                     64:   exit(1);
                     65: }
                     66: 
                     67: int main(int argc, char *argv[])
                     68: {
                     69:   char szArgs[512], *p;  /* new process arguments buffer & temp pointer */
                     70:   char szPgmName[MAX_PATH];  /* name of the program */
                     71:   BOOL fSuccess;  /* API return code */
                     72:   STARTUPINFO si;  /* used for CreateProcess */
                     73:   PROCESS_INFORMATION pi;  /* used for CreateProcess */
                     74:   LPSTR lpszCurDir = NULL;  /* current directory for new process */
                     75:   BOOL bMoreParams;  /* flag end of new process parameter processing */
                     76:   BOOL bWait = FALSE;  /* wait/no wait for new process to end */
                     77:   DWORD dwResult;  /* API return code */
                     78:   DWORD dwCreate = CREATE_NEW_CONSOLE;  /* new process creation flags */
                     79:   BOOL bExtension;  /* input filename have an explicit extension? */
                     80:   int i;
                     81:   char *aExt[] = { ".exe", ".com", ".bat", ".cmd" };
                     82: 
1.1.1.3 ! root       83:   /* Check to make sure we are running on Windows NT */
        !            84:   if( GetVersion() & 0x80000000 )
        !            85:     {
        !            86:     MessageBox(NULL, "Sorry, this application requires Windows NT.\n"
        !            87:         "This application will now terminate.",
        !            88:         "Error: Windows NT Required to Run",  MB_OK );
        !            89:     return(1);
        !            90:     }
1.1       root       91:   /* process all command-line parameters */
                     92:   if (argc < 2)
                     93:     help();
                     94:   memset(&si, 0, sizeof(STARTUPINFO));
                     95:   bMoreParams = TRUE;
                     96:   while(bMoreParams)
                     97:     {
                     98:     argv++;  /* point to the first parameter */
                     99:     if (!*argv) /* if *argv is NULL we're missing the program name! */
                    100:       {
                    101:       puts("Error: missing program name");
                    102:       exit(1);
                    103:       }
                    104:     if ((*argv)[0] == '/' || (*argv)[0] == '-')
                    105:       {
                    106:       strlwr(*argv);
                    107:       switch ((*argv)[1])  /* letter after the '/' or '-' */
                    108:         {
                    109:         case 't':
                    110:           si.lpTitle = &(*argv)[2];  /*  /tTitle */
                    111:           break;
                    112:         case 'd':
                    113:           lpszCurDir = &(*argv)[2];  /*  /dPath */
                    114:           break;
                    115:         case 'h':
                    116:           dwCreate |= HIGH_PRIORITY_CLASS;  /*  /h */
                    117:           break;
                    118:         case 'l':
                    119:           dwCreate |= IDLE_PRIORITY_CLASS;  /*  /l */
                    120:           break;
1.1.1.3 ! root      121:         case 'r':
        !           122:           dwCreate |= REALTIME_PRIORITY_CLASS;  /*  /r */
        !           123:           break;
1.1       root      124:         case 'm':
                    125:           switch ((*argv)[2])
                    126:             {
                    127:             case 'i':
                    128:               si.wShowWindow = SW_MINIMIZE;
                    129:               si.dwFlags |= STARTF_USESHOWWINDOW;
                    130:               break;
                    131:             case 'a':
                    132:               si.wShowWindow = SW_SHOWMAXIMIZED;
                    133:               si.dwFlags |= STARTF_USESHOWWINDOW;
                    134:               break;
                    135:             default:
                    136:               printf("Error: invalid switch - \"%s\"", *argv);
                    137:               help();
                    138:             } /* switch */
                    139:           break;
                    140:         case '?':
                    141:           help();  /* help() will terminate app */
                    142:         case 'w':
                    143:           bWait = TRUE;  /* don't end until new process ends as well */
                    144:           break;
1.1.1.3 ! root      145:         case 'b':
        !           146:           dwCreate |= DETACHED_PROCESS;  /* start detached */
        !           147:           /* detached implies no CREATE_NEW_CONSOLE so fall through */
1.1       root      148:         case 'c':
                    149:           dwCreate &= ~CREATE_NEW_CONSOLE;  /* turn off this bit */
                    150:           break;
                    151:         default:
                    152:           printf("Error: invalid switch - \"%s\"", *argv);
                    153:           help();
                    154:         } /* switch */
                    155:       } /* if */
                    156:     else  /* not a '-' or '/', must be the program name */
                    157:       bMoreParams = FALSE;
                    158:     } /* while */
                    159:   strcpy(szPgmName, *argv++);  /* copy program name as first param */
                    160:   bExtension = (BOOL) strchr(szPgmName, '.');  /* has an extension? */
                    161:   if (!bExtension)
                    162:     strcat(szPgmName, aExt[0]);  /* first extension to try */
                    163:   memset(szArgs, 0, sizeof(szArgs));
                    164:   strcpy(szArgs, szPgmName);  /* first arg: program name */
                    165:   p = strchr(szArgs, 0);  /* point past program name */
                    166:   while (*argv)  /* copy remaining arguments to szArgs separated by spaces */
                    167:     {
                    168:     strcat(p, " ");
                    169:     strcat(p, *argv++);
                    170:     }
                    171:   si.cb = sizeof(STARTUPINFO);
                    172:   i = 1;
                    173:   do
                    174:     {
                    175:     fSuccess = CreateProcess(NULL,  /* image file name */
                    176:         szArgs,  /* command line (including program name) */
                    177:         NULL,  /* security for process */
                    178:         NULL,  /* security for main thread */
                    179:         FALSE,  /* new process inherits handles? */
                    180:         dwCreate,  /* creation flags */
                    181:         NULL,  /* environment */
                    182:         lpszCurDir,  /* new current directory */
                    183:         &si,  /* STARTUPINFO structure */
                    184:         &pi);  /* PROCESSINFORMATION structure */
                    185:     if (!fSuccess)
                    186:       switch (GetLastError())  /* process common errors */
                    187:         {
                    188:         case ERROR_FILE_NOT_FOUND:
                    189:           if (bExtension || i > 3)
                    190:             {
                    191:             puts("Error: program or batch file not found");
                    192:             exit(1);
                    193:             }
                    194:           else
                    195:             strcpy(strchr(szArgs, '.'), aExt[i++]);
                    196:           break;
                    197:         case ERROR_DIRECTORY:
                    198:           puts("Error: bad starting directory");
                    199:           exit(1);
1.1.1.3 ! root      200:         case ERROR_PATH_NOT_FOUND:
        !           201:           puts("Error: bad path");
        !           202:           exit(1);
1.1       root      203:         default:
1.1.1.3 ! root      204:           PERR(0, "CreateProcess");
1.1       root      205:           exit(1);
                    206:         }  /* switch */
                    207:     } while (!fSuccess);
                    208:   /* close pipe handle - child's instance will be closed when terminates */
                    209:   CloseHandle(pi.hThread);
                    210:   if (bWait)  /* wait /Wtime wait flag specified? */
                    211:     {
                    212:     dwResult = WaitForSingleObject(pi.hProcess,  /* object to wait for */
                    213:         (DWORD) -1);  /* timeout time */
1.1.1.3 ! root      214:     PERR(dwResult != -1, "WaitForSingleObject");
1.1       root      215:     }
                    216:   CloseHandle(pi.hProcess);  /* close process handle or it won't die */
                    217:   return(0);
                    218: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.