简体   繁体   English

使用C ++ / CLI将图片插入Excel并收到100x警告C4691

[英]Inserted a picture into Excel using C++/CLI and got 100x warning C4691

I was assigned the task of making a “small” modification to an existing C++/CLI (with Excel automation) application (target framework: .NET4.0, IDE: VS2010). 我的任务是对现有C ++ / CLI(具有Excel自动化)应用程序(目标框架:.NET4.0,IDE:VS2010)进行“小”修改。 The task: insert a couple of pictures (*.jpg) into an Excel worksheet. 任务:在Excel工作表中插入几张图片(* .jpg)。 I was pleased to find here at stackoverflow a thread in which precisely this task was addressed in C#. 我很高兴在stackoverflow上找到一个线程,该线程正是在C#中解决了该任务。 Here is the link: please see the very end of this question 这里是链接: 请参阅此问题的结尾

In the above thread, I followed the instructions provided in the answer from user JMK. 在上面的线程中,我按照用户JMK的答案中提供的说明进行操作。 The code compiles without errors and works! 该代码编译没有错误并且可以正常工作! Indeed, the code successfully places a picture in the worksheet. 的确,代码成功地在工作表中放置了图片。 Unfortunately, I also obtain one hundred C4691 compiler warnings. 不幸的是,我也收到一百个C4691编译器警告。

My code: 我的代码:

    //attributes - used by several different methods
private:
    Excel::Application^ xlApp;
    Excel::_Workbook^ xlBook;
    Excel::Workbooks^ xlBooks;
    Excel::Sheets^ xlSheets;
    Excel::_Worksheet^ xlSheet;
    Excel::Range^ range;
    String^ templateFilename;
    String^ picFilename;

private: System::Void buttonRunExcel_Click(System::Object^  sender, System::EventArgs^  e)
{
//create the Excel Application
xlApp = gcnew Excel::Application();//55 C4691 compiler warnings for this line of code
xlBooks = xlApp->Workbooks;//no compiler warnings here

//open the Excel template - 30 C4691 compiler warnings for the next line of code
xlBook = xlApp->Workbooks->Open(templateFilename, Type::Missing, false, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing);

xlSheets = xlBook->Worksheets;//no compiler warnings here

//set the active worksheet to sheet 3
xlSheet = (Excel::_Worksheet^)xlSheets->Item[3];//no compiler warnings here

//insert the picture - 15 C4691 compiler warnings for the next line of code
xlSheet->Shapes->AddPicture(picFilename, Core::MsoTriState::msoFalse, Core::MsoTriState::msoCTrue, 100, 200, 640, 480);

} }

My references: 我的参考资料:

    using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
using namespace Microsoft::Office::Core;
using namespace Microsoft::Office::Interop::Excel;

A sample compiler warning: 示例编译器警告:

warning C4691: "Microsoft::Office::Core::Assistant": type referenced was expected in unreferenced assembly "office", type defined in current translation unit used instead. 警告C4691:“ Microsoft :: Office :: Core :: Assistant”:在未引用的程序集“办公室”中期望引用的类型,而是在当前翻译单元中定义的类型。 This diagnosis occurred while importing type 'Microsoft: Office:Interop:Excel:ApplicationClass' from Assembly "Microsoft.Office.Interop.Excel, Version = 12.0.0.0, culture = neutral, PublicKeyToken = 71e9bce111e9429c". 从程序集“ Microsoft.Office.Interop.Excel,版本= 12.0.0.0,区域性=中性,PublicKeyToken = 71e9bce111e9429c”中导入类型“ Microsoft:Office:Interop:Excel:ApplicationClass”时,发生了此诊断。

MSDN's description of this compiler warning was not particularly helpful (for me). MSDN对此编译器警告的描述对我而言不是特别有用。 I don't wish to simply ignore the warnings (foolish) nor do I want to “turn off” the warnings using pragma warning (sloppy). 我既不想简单地忽略警告(愚蠢的),也不想使用编译指示(草率)来“关闭”警告。

How can I eliminate warning C4691? 如何消除警告C4691? All advice, comments, even (constructive) criticism are gratefully appreciated. 感谢所有建议,评论,甚至(建设性)批评。 Thanks 谢谢

    xlApp = gcnew Excel::Application();

There's a fair amount of automagic happening here, the kind that doesn't actually works so well in the C++ IDE. 这里发生了很多自动魔术,这种魔术实际上在C ++ IDE中不能很好地起作用。 Unlike the VB.NET and C# IDEs, the languages normally used to write Office interop code. 与VB.NET和C#IDE不同,这些语言通常用于编写Office互操作代码。

Excel::Application is an interface , not a class. Excel :: Application是一个接口 ,而不是一个类。 And of course it is never possible to create an instance of an interface, it is an abstract type. 当然,永远不可能创建接口的实例,它是抽象类型。 The C++/CLI compiler of course knows that this isn't possible and goes hunting for a class that implements the interface. 当然,C ++ / CLI编译器知道这是不可能的,因此会寻找实现该接口的 It finds it by looking for the [CoClassAttribute] attribute on the interface type, it points to Excel::ApplicationClass, a synthetic .NET class generated by the type library importer. 它通过在接口类型上查找[CoClassAttribute]属性来找到它,它指向Excel :: ApplicationClass,这是由类型库导入程序生成的合成.NET类。 Notable is that the IntelliSense parser doesn't know about this trick and puts red squiggles under the statement. 值得注意的是,IntelliSense解析器不知道此技巧,而是将红色花体放在该语句下。 You'll get rid of it by making the substitution yourself: 您可以自己进行替换来摆脱它:

    xlApp = gcnew Excel::ApplicationClass();

Onwards to the C4691 warnings. 继续执行C4691警告。 The Excel type library uses another type library that contains common Office type declarations. Excel类型库使用另一个包含常见Office类型声明的类型库。 You apparently already figured this out and properly added a reference to MSO.DLL, getting types in the Microsoft::Office::Core namespace. 您显然已经知道了这一点,并正确添加了对MSO.DLL的引用,从而获得了Microsoft :: Office :: Core命名空间中的类型。 But that's a mapped namespace name, the type library name is actually "Office", not "Microsoft.Office.Core". 但这是一个映射的名称空间名称,类型库名称实际上是“ Office”,而不是“ Microsoft.Office.Core”。

So the C++/CLI compiler notices the discrepancy, ApplicationClass refers to a interface named Assistant in the Office type library so it expects an assembly named "Office" to be available. 因此,C ++ / CLI编译器注意到了差异,ApplicationClass引用了Office类型库中名为Assistant的接口,因此它希望有一个名为“ Office”的程序集可用。 Which is the normal way a type library name is mapped to an assembly name. 类型库名称映射到程序集名称的正常方法。 In other words, it doesn't know that the namespace name got mapped. 换句话说,它不知道名称空间名称已映射。 Nor could it know, it didn't do that mapping. 它也不知道,它没有那样做映射。 It was done by a registry key. 这是通过注册表项完成的。

This is a warning and not an error because it does actually turns out correct in the end, it does properly map it to one of the available assembly reference. 这是一个警告,而不是错误,因为最终它实际上确实正确,并且确实将其正确映射到可用的程序集引用之一。 The one you expect to be used, Microsoft.Office.Core. 您期望使用的是Microsoft.Office.Core。 That this happened correctly is a wee bit of a gamble, it would technically be possible for you to forget adding the reference to MSO.DLL and have another interop type named "Assistant". 正确执行此操作只是一场赌博,从技术上讲,您可能会忘记将引用添加到MSO.DLL并拥有另一个名为“ Assistant”的互操作类型。 Boomshakalaka if you ignore the warning then and use the interface. Boomshakalaka如果您忽略警告,然后使用界面。

So go ahead and set your laser to stun: 因此,继续进行操作,使激光眩晕:

    #pragma warning(disable:4691)
    using namespace Microsoft::Office;
    using namespace Microsoft::Office::Interop;

I changed the using statements, the ones you quoted were wrong and don't allow using "Excel::Application" and "Core::MsoTriState", another fruitful source of compile errors. 我更改了using语句,您引用的语句是错误的,并且不允许使用“ Excel :: Application”和“ Core :: MsoTriState”,这是另一个富有成效的编译错误源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM