MFC工程在release版本下的问题求助

qq_34760393 2017-07-20 10:48:40
前一阵子用mfc做了一个软件安装和卸载包。功能全部都现实了,在debug下也没有任何问题。然后用release编译时虽然也没有报错,不过在安装完成后卡住不动了。调试了很久都没有找到问题出在哪里。

我的逻辑是这样的。请大佬们耐心看完。 = = !

打开程序点击安装进入进度条的界面。这里用的是多线程(因为我的背景是gif图)。然后设置了一个定时器,每隔半秒点击一次隐藏的button。第一次点击进入多线程处理解压以及创建快捷方式等操作,操作完成后,会给一个标记,下一次定时器点击隐藏的button时,会结束本对话框,进入最后完成安装的界面。

debug版本没有任何问题,但是release版本, 进度条走到最后的时候,就卡住不动了。无法进入完成安装界面。

我经过调试发现,多线程里面所有的逻辑它都完成了,也就是说,安装已经安装好了。但是在结束多线程后,定时器多数情况都不会再点击隐藏的button(偶尔又会点击,但是就算点击,运行了xxxdlg.DoModal()也没有生成新的对话框。这里我非常不解!)

楼下贴出我的消息点击函数和线程函数,望大佬们指点一下!
...全文
298 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-07-24
  • 打赏
  • 举报
回复
学会使用dumpbin.exe /exports advapi32.dll查看其导出的函数名。
xiaohuh421 2017-07-24
  • 打赏
  • 举报
回复
release版本有问题. 还是多打日志吧.
cutmelon 2017-07-24
  • 打赏
  • 举报
回复
引用 7 楼 qq_34760393 的回复:
[quote=引用 6 楼 cutmelon 的回复:] 问题应该出现在这三行 EndDialog(1); CMyFinishDlg dlg; dlg.DoModal(); 你都要关闭对话框了,下一个对话框还是局部变量,这处理办法肯定是不对的。正确的办法应该是由copydlg的父窗口来调用finishdlg。 另外,用定时器监控线程是没有效率的做法,应该在线程结束时发一个自定义消息出来,copydlg自行关闭并把线程结果输出到父窗口,父窗口根据结果决定是否弹出finishdlg。我猜你的copydlg也是domodal的吧
是的,这个项目是我第一次用MFC,之前啥都不知道= =。最后我把程序换成静态编译,然后我也不知道改了些什么,就运行通过了。另外定时器哪里确实很浪费效率。不过当时也不知道用什么办法了。 谢谢啦。 对了,我今天还遇到一个问题,我把我的软件在XP sp3系统上测试,安装程序没啥问题,但是运行卸载程序包的时候,提示 “无法定位程序输入点 RegDeleteTreew 于动态链接库ADVAPI32.dll上” 我在网上下了ADVAPI32.dll拷到C:\WINDOWS\system32目录下,还是不行。你知道是怎么回事不啊?[/quote]这个你看一下MSDN就知道了,RegDeleteTree是vista之后的操作系统才提供的api,xp必须是没有的,自己枚举删除吧
qq_34760393 2017-07-22
  • 打赏
  • 举报
回复
引用 6 楼 cutmelon 的回复:
问题应该出现在这三行 EndDialog(1); CMyFinishDlg dlg; dlg.DoModal(); 你都要关闭对话框了,下一个对话框还是局部变量,这处理办法肯定是不对的。正确的办法应该是由copydlg的父窗口来调用finishdlg。 另外,用定时器监控线程是没有效率的做法,应该在线程结束时发一个自定义消息出来,copydlg自行关闭并把线程结果输出到父窗口,父窗口根据结果决定是否弹出finishdlg。我猜你的copydlg也是domodal的吧
是的,这个项目是我第一次用MFC,之前啥都不知道= =。最后我把程序换成静态编译,然后我也不知道改了些什么,就运行通过了。另外定时器哪里确实很浪费效率。不过当时也不知道用什么办法了。 谢谢啦。 对了,我今天还遇到一个问题,我把我的软件在XP sp3系统上测试,安装程序没啥问题,但是运行卸载程序包的时候,提示 “无法定位程序输入点 RegDeleteTreew 于动态链接库ADVAPI32.dll上” 我在网上下了ADVAPI32.dll拷到C:\WINDOWS\system32目录下,还是不行。你知道是怎么回事不啊?
zgl7903 2017-07-20
  • 打赏
  • 举报
回复
调试运行, 卡住时,点击暂停,然后看看各个程序停下来的位置, 注意是否有越界 死锁等操作
qq_34760393 2017-07-20
  • 打赏
  • 举报
回复
错了错了,我刚刚换成静态库编译调试后,我发现Timer应该是没有问题的,多线程结束后也能进入Timer触发的函数,但是程序运行到 EndDialog(1); CMyFinishDlg dlg; dlg.DoModal(); 这里时,能结束本窗口,但是结束窗口后没办法创建新的窗口
qq_34760393 2017-07-20
  • 打赏
  • 举报
回复
引用 2 楼 worldy 的回复:
安装干嘛要多线程,安装一般是拷贝文件,而磁盘通道只有一个,你用多线程也要使用同步机制,因此,多线程是完全没有必要的
我背景用的gif图,如果用单线程gif图会卡着不动,而且用debug版本没有任何问题。release版本我不知道是因为多线程的问题还是定时器的问题。因为在结束多线程后,定时器就不能触发了。
worldy 2017-07-20
  • 打赏
  • 举报
回复
安装干嘛要多线程,安装一般是拷贝文件,而磁盘通道只有一个,你用多线程也要使用同步机制,因此,多线程是完全没有必要的
qq_34760393 2017-07-20
  • 打赏
  • 举报
回复

//这一段是定时器定时点击的函数。m_bIsBeginCopy初始化为真,点击一次后为假。
// m_bHasFinish初始化为假,完成线程逻辑后为真 。
void CMyCopyDlg::OnBnClickedButton3()
{
	// TODO:  在此添加控件通知处理程序代码
	if (m_bHasFinish == true && m_Progress.GetPos() == m_pro_maxsize)
	{
		m_Progress.SetPos(0);
		m_Progress.EnableWindow(false);
		EndDialog(1);
		CMyFinishDlg dlg;
		dlg.DoModal();
	}
	if (m_bIsBeginCopy == true)
		m_pThread = AfxBeginThread(CMyCopyDlg::CopyFileThenCreatSC, this);
	m_bIsBeginCopy = false;
}

UINT CMyCopyDlg::CopyFileThenCreatSC(LPVOID pParm)
{
	CStringArray name;
	CMyCopyDlg* p = (CMyCopyDlg*)pParm;
	int res = p->UnCompresss(_T(""), name, g_Package.m_setup_filepath);
	if (g_Package.m_Component.hasTableSC == true)  //若选择创建则创建桌面快捷方式
		g_Package.CreateTableSC();
	if (g_Package.m_Component.hasMenubarSC == true)   //若选择创建则创建开始菜单快捷方式
		g_Package.CreateMenuSC();
	if (g_Package.m_Component.hasTaskbarSC == true)  //若选择创建则创建任务栏快捷方式
	{
		LPITEMIDLIST PIDL;
		SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &PIDL);
		TCHAR dir[MAX_PATH];
		ZeroMemory(dir, MAX_PATH);
		SHGetPathFromIDList(PIDL, dir);
		CString LinkFilename = dir; //得到菜单目录
		int nRet = (int)::ShellExecute(NULL, _T("TaskbarPin"),
			LinkFilename + _T("\\") + g_Package.m_AppInfo.AppName + _T(".lnk"),
			NULL, NULL, SW_SHOW);
		//返回值大于32表示成功  
		if (nRet <= 32)
			AfxMessageBox(_T("无法将快捷方式固定到任务栏!"));
	}
	g_Package.WriteRegedit(); //将关键信息写入注册表
	p->m_bHasFinish = true;
	return res;
}


cutmelon 2017-07-20
  • 打赏
  • 举报
回复
问题应该出现在这三行 EndDialog(1); CMyFinishDlg dlg; dlg.DoModal(); 你都要关闭对话框了,下一个对话框还是局部变量,这处理办法肯定是不对的。正确的办法应该是由copydlg的父窗口来调用finishdlg。 另外,用定时器监控线程是没有效率的做法,应该在线程结束时发一个自定义消息出来,copydlg自行关闭并把线程结果输出到父窗口,父窗口根据结果决定是否弹出finishdlg。我猜你的copydlg也是domodal的吧

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧