|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.