CoCreateInstance调用返回代码0x80040154的一种解决方法
CoCreateInstance调用返回代码0x80040154的一种解决方法
前面的一篇博文中总结了开发Windows Thumbnail Handler的一些经验。在公司实际项目中,需要同时针对图片和视频实现缩略图。同时还要在图片和视频文件的顶部加上LOGO,如下:
于是考虑了一下实现方案:
- LOGO资源采用Base64编码编译到DLL中去;
- 公司自有的图片和视频文件进行全景拼接时依赖一串参数,而这串参数需要从文件中提取。因此采用RecipeThumbnailProvider实现IInitializeWithFile接口比较合适,这样能得到文件路径,具备更灵活的可操作性;
- LOGO资源使用Windows自带的解码库来进行解码,也就是Windows Image Component(WIC)。
这么一思考,还是挺靠谱的。于是就动手开始编码,编写了一个解码LOGO资源的函数:
/*Decode the Base64-encoded string to get logo resources.*/
HRESULT RecipeThumbnailProvider::GetLogoFromString(LPCWSTR encodedString, UINT* width, UINT* height, PBYTE* rawPixels)
{
IStream* pImageStream = NULL;
HRESULT hr = E_FAIL;
DWORD dwDecodedImageSize = 0;
DWORD dwSkipChars = 0;
DWORD dwActualFormat = 0;
if (CryptStringToBinary(encodedString, NULL, CRYPT_STRING_BASE64, NULL, &dwDecodedImageSize, &dwSkipChars, &dwActualFormat))
{
BYTE* pbDecodedImage = static_cast<BYTE*>(LocalAlloc(LPTR, dwDecodedImageSize));
if (pbDecodedImage)
{
if (CryptStringToBinary(encodedString, lstrlen(encodedString), CRYPT_STRING_BASE64, pbDecodedImage, &dwDecodedImageSize, &dwSkipChars, &dwActualFormat))
{
pImageStream = SHCreateMemStream(pbDecodedImage, dwDecodedImageSize);
if (pImageStream != NULL)
{
IWICImagingFactory* pImageFactory;
hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pImageFactory));
LOGINFO(L"CoCreateIntance() returns 0x%x", hr);
if (SUCCEEDED(hr))
{
IWICBitmapDecoder* pDecoder;
hr = pImageFactory->CreateDecoderFromStream(pImageStream, &GUID_VendorMicrosoft, WICDecodeMetadataCacheOnDemand, &pDecoder);
if (SUCCEEDED(hr))
{
IWICBitmapFrameDecode* pBitmapFrameDecode;
hr = pDecoder->GetFrame(0, &pBitmapFrameDecode);
if (SUCCEEDED(hr))
{
IWICBitmapSource* pBitmapSourceConverted = NULL;
WICPixelFormatGUID guidPixelFormatSource;
hr = pBitmapFrameDecode->GetPixelFormat(&guidPixelFormatSource);
if (SUCCEEDED(hr) && (guidPixelFormatSource != GUID_WICPixelFormat24bppBGR))
{
IWICFormatConverter* pFormatConverter;
hr = pImageFactory->CreateFormatConverter(&pFormatConverter);
if (SUCCEEDED(hr))
{
hr = pFormatConverter->Initialize(pBitmapFrameDecode, GUID_WICPixelFormat24bppBGR, WICBitmapDitherTypeNone, NULL, 0, WICBitmapPaletteTypeCustom);
if (SUCCEEDED(hr))
{
hr = pFormatConverter->QueryInterface(&pBitmapSourceConverted);
}
pFormatConverter->Release();
}
}
else
{
hr = pBitmapFrameDecode->QueryInterface(&pBitmapSourceConverted);
}
if (SUCCEEDED(hr))
{
hr = pBitmapSourceConverted->GetSize(width, height);
if (SUCCEEDED(hr))
{
WICRect rect = { 0, 0, *width, *height };
*rawPixels = static_cast<BYTE*>(LocalAlloc(LPTR, (*width)*(*height)*3));
hr = pBitmapSourceConverted->CopyPixels(&rect, (*width) * 3, (*width)*(*height) * 3, *rawPixels);
}
else
{
*width = 0;
*height = 0;
*rawPixels = NULL;
}
pBitmapSourceConverted->Release();
}
pBitmapFrameDecode->Release();
}
pDecoder->Release();
}
pImageFactory->Release();
}
pImageStream->Release();
}
}
}
LocalFree(pbDecodedImage);
}
return hr;
}
当注册好COM组件开始使用时,在本机上测试简直完美。满以为就这么搞定了,然而不是。在另外一台Win7机器上测试时,缩略图中并没有出现想象中的LOGO。一看日志文件,发现一直在报:CoCreateInstance()调用返回0x80040154。于是下面的代码都没执行,LOGO资源自然没有加载成功了。那么CoCreateInstance()为啥会返回0x80040154呢?这个代码又意味着什么嗯?从网上的搜索结果来看,0x80040154是表示"Class Not Registered"。也就是说COM类并没有注册,在注册表\HKEY_CLASSES_ROOT\CLSID\下面也就没有类ID了。我们程序中使用了WIC组件来解码图片,那么难道是WIC组件类没有注册吗?
再一想,开发时采用的一直是Windows10,可以正常运行。到了Windows7上为啥就不行了呢?难道是WIC在Windows7上不支持?这个怀疑显然是不成立的,从MSDN上来看从XP SP2就开始支持了啊:
那么难道是参数给的不对?以CLSID_WICImagingFactory为关键字一搜索果然搜到了一篇帖子:CLSID_WICImagingFactory在Windows10上被解析为了CLSID_WICImagingFactory2:
而这个GUID在Windows7上是不存在的(搜索注册表即可看到结果):
自然CoCreateInstance()调用就会返回0x80040154了。解决方案就是传递CLSID_WICImagingFactory1给CoCreateInstance()。这样就能同时兼容Windows10和Windows7了。
CoCreateInstance调用返回代码0x80040154的一种解决方法相关推荐
- python无法使用1号gpu_详解tensorflow2.x版本无法调用gpu的一种解决方法
最近学校给了一个服务器账号用来训练神经网络使用,服务器本身配置是十路titan V,然后在上面装了tensorflow2.2,对应的python版本是3.6.2,装好之后用tf.test.is_gpu ...
- bs4 乱码_Python BeautifulSoup中文乱码问题的2种解决方法
解决方法一: 使用python的BeautifulSoup来抓取网页然后输出网页标题,但是输出的总是乱码,找了好久找到解决办法,下面分享给大家 首先是代码 复制代码 代码如下: from bs4 im ...
- php无限极 left right,php无限极分类实现的两种解决方法
本篇文章介绍了,在php中无限极分类实现的两种解决方法.需要的朋友参考下 method of classify one<?php /* reader: 这是自己写的无限极分类实现方法 里面的编辑 ...
- android中view手势滑动冲突的两种解决方法
android中view手势滑动冲突的解决方法,主要解决方法有两种,外部和内部拦截.有需要的可以参考下. Android手势事件的冲突跟点击事件的分发过程息息相关,由三个重要的方法来共同完成,分别是: ...
- win7 计算机管理的命令,Win7运行cmd命令提示“命令提示符已被系统管理员停用”三种解决方法...
在运行win7操作系统中,经常使用运行命令对系统进行一些设置.最近有用户在Win7系统下运行CDM命令时,提示"命令提示符已被系统管理员停用"(如图),导致无法正常使用命令功能,遇 ...
- ARM32平台系统crash(系统崩溃) 问题定位的一种解决方法
说明 分享一种crash问题定位的一种解决方法,仅供参考. ARM32平台上通过错误使用内存,触发系统异常,系统崩溃.系统异常被挂起后,能在串口中看到异常调用栈打印信息和关键寄存器信息. 如下所示,e ...
- 没有注册类别的一种解决方法
没有注册类别的一种解决方法 修改以前老的vs程序,其中用到了老的串口控件,MSCOMM32.OCX, 按照要求注册完后,报错"没有注册类别",重启后依然报错, 查找到网友提供的解决 ...
- scrapy:Unknown command: crawl 的3种解决方法
一.报错 报错的界面截图: 报错解析:该报错是找不到配置文件,无法执行douban 项目.可能原因如下: 路径不对:没有切换路径到douban 项目下或没有把douban 文件夹添加到一个sys路径: ...
- php取数组中连续数,PHP实现求连续子数组最大和问题2种解决方法
本文实例讲述了PHP实现求连续子数组最大和问题2种解决方法.分享给大家供大家参考,具体如下: 问题描述 求子数组的最大和 题目描述: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整 ...
最新文章
- Mozilla 宣布引入二步认证
- 图像的打开、修改、显示和保存示例(OpenCV 2.0)
- Django MPTT —— 概述
- javaweb连接不上mysql怎么办_java web应用连接mysql会突然connection连接失败
- redis服务器端和客户端启动
- 鸿蒙还是不是安卓,华为捐赠鸿蒙核心架构!是否形成“三足鼎立”?
- mysql并发 node_nodejs写入mysql单次数据量过大的解决方法_沃航科技
- 泡沫or趋势?我们到底需要什么样的区块链?
- 已知若干点求圆心_【求精干货】高中数学知识点总结归纳高一学生必须掌握
- Linux安全加固--系统相关
- 三、K8s常见操作命令
- RCP中如何使用代码安装、运行plugins
- 求一个数因数个数c语言,【代码】求一个数的因数和、求优化、顺便也供新人参考算法...
- elasticjob 源码分析
- 【antdesign】表单布局和校验
- VSCode如何更换背景图片
- IntelliJ IDEA更换主题样式分享
- 如何用手机保存APP上的视频
- 网络安全——Burpsuite
- 高智商与低智商的区别_体内平衡与智力的定义
热门文章
- 常见解压缩软件与其zip格式
- db2建库、建表空间基本流程
- LINQ语法类似于SQL的语法
- 解决 html5 input type='number' 类型可以输入e
- OpenStack对象存储——Swift
- 转Oracle性能参数—经典常用
- 网页设计中时尚​​的下拉菜单案例
- html怎么限制密码字母个数字,怎样限制密码长度,并且只能为字母数字及下划线组成?...
- 最长上升子序列模板 hdu 1087 Super Jumping! Jumping! Jumping!
- 解决ORA-01578错误一例