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