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

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

unix.superglobalmegacorp.com

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