MFC 单文档 带参数调试

项目用MFC 单文档开发。今天准备带参数调试,发现在 “命令参数”栏 填1时,程序运行会报错,提示"没有找到E:\xxx\1".

原来把参数数据当成了执行模块。这个MessageBox并不是我代码弹出,所以不好判断在哪里报错。

这里就想到VS环境中,下API断点。网上查了一下资料,Ctrl+B手动添加断点:{,,USER32.DLL}_MessageBoxW@16

分二步,加载符号和下断点

1.想下API断点 的前提是有符号文件。  如果是下WINDOWS API还是很方便的。在调试模式下直接去模块窗口 然后在需要下API所在模块上右键 选择加载符号 微软符号器  就可以从网上下载并加载此DLL的符号,如果是第三方的需要指定符号的路径去加载。

2. 比如我们要对MessageBoxW这个API下断点,就可以直接CTRL+B 然后输入 {,,USER32.DLL}_MessageBoxW@16  (后面的16是因为它有4个参数,每个参数4字节)  如果下的API是MessageBeep那么就是 {,,USER32.DLL}_MessageBeep@4.

然后在运行程序 当有人调用这些API的时候就会停留在 反汇编窗口。

在VS2017中好像可以“user32.dll!MessageBoxW” 下API断点(模块名称+“!” + 函数名)。

这样再次报错弹框时,程序就被断了下来。通过栈回朔,可以看到在“BOOL CSimpleDocTestApp::InitInstance()”中

不难定位到,在这里有解析参数的操作

关于这两个函数的解析,网上资料一堆。

发现ParseCommandLine调用前,cmdInfo.m_nShellCommand = FileNew,cmdInfo.m_strFileName = "";

当ParseCommandLine(CCommandLineInfo)后,cmdInfo.m_nShellCommand = FileOpen,cmdInfo.m_strFileName = "1"(即 调试参数);

问题出现在ParseCommandLine(CCommandLineInfo)中,跟进去查看:

void CWinApp::ParseCommandLine(CCommandLineInfo& rCmdInfo)
{
	for (int i = 1; i < __argc; i++)
	{
		LPCTSTR pszParam = __targv[i];
		BOOL bFlag = FALSE;
		BOOL bLast = ((i + 1) == __argc);
		if (pszParam[0] == '-' || pszParam[0] == '/')
		{
			// remove flag specifier
			bFlag = TRUE;
			++pszParam;
		}
		rCmdInfo.ParseParam(pszParam, bFlag, bLast);
	}
}

可以看到,当(pszParam[0] == '-' || pszParam[0] == '/')  参数开头是字符'-'或者'/'时,字符后的数据被认定是 启动进程参数。

问题到这里已经明了,启动单文档程序,带参数时,参数前面加上'-'或者'/',否则在ParseCommandLine(CCommandLineInfo)和ProcessShellCommand(cmdInfo)时就会报错。

正解传参方式:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值