从Win32程序中的主函数中获取命令行参数

本文介绍在Win32应用程序中如何解析命令行参数,包括利用WinMain函数的lpCmdLine参数、GetCommandLine()函数及CommandLineToArgvW()函数等方法,并提及了全局变量__argc和__argv的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【翻译文章,原文来自:http://codingmisadventures.wordpress.com/2009/03/10/retrieving-command-line-parameters-from-winmain-in-win32/

在标准C或者Win32控制台程序的main函数中,它们都有两个参数:"argc" 和 "argv",如下所示:

int main(int argc, char * argv[]) ...

这些参数帮助我们为程序传入命令行参数。"argc"为命令行参数的个数,"argv"则为传入参数的数组列表。但是当我们在Visual Studio中创建Win32 GUI程序的时候,WinMain变成程序的入口函数,而该函数并没有"argc" 和"argv"参数,那我们怎样给Windows程序传入命令行参数呢?Windows程序中又怎样取得这些传入的参数呢?

lpCmdLine 参数

第一个方案就来自WinMain函数自身。让我们看一个典型的WinMain函数声明:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)..

如声明所示,WinMain函数有一个类型为"LPSTR(char*)"的参数"lpCmdLine". 这个变量存放着命令行中除程序自身名字外的剩下所有部分。例如,我们有一个名字为"test.exe"的应用程序,当用下面的命令行运行该程序时

test.exe Some arguments here

变量lpCmdLine的值即为"Some arguments here"。尽管该方法不像"argc"和"argv"一样非常方便,但它是获取命令行参数的方法之一。我们需要自己写程序去分析lpCmdLine字符串,这增加了程序的复杂度。

【译注:Windows程序代码同时ANSI版本和UNICODE版本接口。其中WinMain函数为ANSI版本,wWinMain为UNICODE版本。从Visual Studio创建出来的代码主函数命名为_tWinMain。这个函数名会根据当前工程有没有定义_UNICODE宏而在编译时翻译成上面两个不同版本。当翻译成WinMain函数时候,lpCmdLine的类型为LPSTR,而当翻译成wWinMain函数时候,lpCmdLine的类型为LPWSTR,即宽字符数组】

GetCommandLine()函数

另外一个方法就是使用GetCommandLine() API。这个函数返回整个命令行,它把程序自身名称(包括程序的绝对路径)和所有参数放在一个字符串中。该函数非常类似于对lpCmdLine的直接访问。但它的一个好处是能够根据你当前工程的设置自动映射到GetCommandLineA()或者GetCommandLineW()函数。因此解决了访问Unicode命令行输入的问题。但是它还是既没有提供命令行参数数目,也没有类似argv那样把参数自动分割成独立变量的能力。

CommandLineToArgvW()函数

最后一个我要讨论的方法是CommandLineToArgvW函数。这个函数只有Unicode宽字符版本,没有对应的CommandLineToArgvA函数。它的声明如下:

 
LPWSTR *CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs)

该函数和'argc'/'argv'一样简单,但是它并不是在Windows程序中直接访问argc和argv变量。如声明所示,函数接受两个参数,一个是需要解析的Unicode命名行字符串,另外一个是指向整型变量的指针。函数在返回时把参数数目存到这个整型变量中。

函数返回一个类似于'argv'的字符串数组。让我们看一个例子:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    LPWSTR *szArgList;
    int argCount;

     szArgList = CommandLineToArgvW(GetCommandLine(), &argCount);
     if (szArgList == NULL)
     {
         MessageBox(NULL, L"Unable to parse command line", L"Error", MB_OK);
         return 10;
     }

     for(int i = 0; i < argCount; i++)
     {
         MessageBox(NULL, szArgList[i], L"Arglist contents", MB_OK);
     }

     LocalFree(szArgList);
     return 0;
}

如上所示,通过这个函数,我们可以取得命令行参数的数目(argc)和一个字符串列表(argv)。这里唯一要注意的事情是该函数会给返回参数列表分配一块内存。当我们用完列表后需要手动地释放该内存,否则就会有内存泄露

EDIT: Variables __argc and __argv

另外,微软提供了全局变量__argc 和__argv。这两个变量由Windows在运行时自动赋值。其中__argv有ASCII和Unicode版本,分别为__argv和__wargv。要使用这两个全局变量,需要引用"stdlib.h"头文件(该头文件已经在windows.h中引用)。为了根据工程设置来自动选择ASCII还是Unicode版本变量,我们可以引用"TCHAR.h"头文件并访问__targv变量。代码如下

extern int __argc;

extern TCHAR* __targv;

这个方法是所有方法中最简单的一个。但它的代价是程序需要链接VC++运行时库(例如"msvcrt.dll")。当然99%的Windows程序几乎都要使用这个运行库:)

Del.icio.us : 命令行参数 WinMain

要在Python中使用win32实现OCR(光学字符识别),你可以使用`pywin32`库来调用Windows API,并结合Tesseract OCR引擎的Windows版本。以下是一个基本的步骤指南和代码示例。 首先,确保安装了`pywin32`和Tesseract OCR引擎: 1. 安装`pywin32`: ```bash pip install pywin32 ``` 2. 下载并安装Tesseract OCR。确保将其安装在系统路径中,或者将安装目录添加到系统路径中。你可以从这里获取Tesseract OCR的Windows安装包:https://github.com/UB-Mannheim/tesseract/wiki 安装完成后,你可以使用以下代码来实现OCR功能: ```python import win32gui import win32ui import win32con import subprocess def capture_screen(): # 获取窗口句柄 hwnd = win32gui.GetDesktopWindow() # 获取窗口设备上下文 wdc = win32gui.GetWindowDC(hwnd) # 创建一个设备上下文对象 dcobj = win32ui.CreateDCFromHandle(wdc) # 创建一个与该设备上下文相关的设备上下文对象 cdc = dcobj.CreateCompatibleDC() # 创建一个与窗口兼容的位图 dataBITMAP = win32ui.CreateBitmap() dataBITMAP.CreateCompatibleBitmap(dcobj, 800, 600) # 将新创建的位图选入兼容设备上下文中 cdc.SelectObject(dataBITMAP) # 复制设备上下文内容到新的位图中 cdc.BitBlt((0, 0), (800, 600), dcobj, (0, 0), win32con.SRCCOPY) # 保存位图到文件 dataBITMAP.SaveBitmapFile(cdc, 'screenshot.bmp') # 释放设备上下文和设备上下文对象 win32gui.ReleaseDC(hwnd, wdc) win32ui.DeleteDC(cdc) win32ui.DeleteObject(dataBITMAP.GetHandle()) return 'screenshot.bmp' def ocr_image(image_path): # Tesseract命令行命令 command = ['tesseract', image_path, 'out'] # 执行命令 process = subprocess.run(command, stdout=subprocess.PIPE) print(process.stdout.decode()) # 主函数 def main(): # 截图并保存为位图文件 image_path = capture_screen() # 对截图执行OCR ocr_image(image_path) # 运行程序 if __name__ == "__main__": main() ``` 这段代码首先通过Windows API截取当前屏幕的内容并保存为位图文件,然后使用Tesseract OCR对这个位图文件进行文字识别。 请注意,你需要根据你的操作系统和安装的Tesseract版本调整`tesseract`命令中的参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值