【问题标题】:Pass command line args to COM component in WPF project将命令行参数传递给 WPF 项目中的 COM 组件
【发布时间】:2016-07-23 00:40:30
【问题描述】:

所以这里是设置:

  • 使用 xaml 进行布局的 C# WPF 主项目

  • 我们有一个古老的 MFC activeX / COM 组件可以使用

    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);
    

    获取命令行参数并根据它们进行操作。 这个旧项目无法更改 :(

  • 用于包装 COM 组件的 Windows 窗体类库项目。

组件被添加到 xaml 视图中,如下所示:

var host = new WindowsFormsHost();
var activeX = new Viewer();
host.Child = activeX;
var grid = new Grid();            
grid.Children.Add(host);
Content = grid

如何传递 COM 组件在执行 ParseCommandLine(cmdInfo); 时将获取的“命令行参数”?

更新:

我的winform使用:private AxPLUGINXLib.AxPluginX axPluginX1;

类定义如下。仍然不确定如何将命令行参数传递给它。

    [Clsid("{9ab948c6-b1a9-11d2-ac9b-0040c72d55ed}")]
    [DesignTimeVisible(true)]
    public class AxPluginX : AxHost
    {
        public AxPluginX();

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [DispId(-525)]
        public virtual int ReadyState { get; }

        public event _DPluginXEvents_ReadyStateChangeEventHandler ReadyStateChange;

        public virtual void AboutBox();
        protected override void AttachInterfaces();
        protected override void CreateSink();
        protected override void DetachSink();
    }

【问题讨论】:

  • 你在问你的 COM 组件的接口是什么。恕我直言,这很愚蠢。你是坐在这些信息上的人。
  • 这无济于事。我知道我想传递给 COM 组件的字符串。我不知道如何通过它。就像我说的那样,它会在独立的情况下从命令行参数读取它。我需要在 COM 组件中填充 CCommandLineInfo.m_strFileName 字段以使其工作。
  • 这是 COM .exe 还是 COM .dll?如果它是一个 .exe,也许你可以通过它自己的进程(你可以在其中指定任何你想要的命令行)打开并启动 COM 对象,然后使用 GetObject(而不是 CreateObject)获取实例。
  • @TylerZale:既然你“知道字符串”,为什么你的问题中没有这些信息?无论如何,有了更多信息,读者可能会对您的问题做出不那么无知的猜测。由于信息的稀疏性和对我的有用评论的双重加分不友好的回应而投了反对票。
  • @John Wu:为此有一个独立的 .exe。它通过其 .ocx 作为参考加载。我们正在尝试将这个组件包含在我们的 UI 中,以便我们可以对其进行屏幕捕获/共享等,因此如果有一种捕获其窗口输出的好方法,我们只能将它作为子可执行文件生成?

标签: c# c++ wpf xaml mfc


【解决方案1】:

只要你在做一些疯狂的事情......你可以:

向您的解决方案添加一个新的 C++/CLI 项目:Visual C++ -> CLR -> 类库。

然后像这样向 C++/CLI 类添加一个函数:

#pragma once

#include <cstdlib>
#include <vcclr.h>
#include <vector>
#include <algorithm>
#include <iterator>

using namespace System;
using namespace System::Runtime::InteropServices;

std::vector<wchar_t> ArgBuffer(4096);
std::vector<wchar_t*> ArgTable;

namespace ManagedCpp {

    public ref class Class1
    {
    public:
        static void PassCommandLine(array<String^>^ args)
        {
            size_t totalChars = 0;
            for (int i = 0; i < args->Length; i++)
            {
                totalChars += args[i]->Length + 1; // include null-terminator
            }

            ArgBuffer.resize(totalChars);
            ArgTable.resize(args->Length);

            auto pDst = &ArgBuffer[0];

            for (int i = 0; i < args->Length; i++)
            {
                pin_ptr<const wchar_t> pStr = PtrToStringChars(args[i]);
                size_t len = args[i]->Length + 1; // include null-terminator

                std::copy_n(
                    static_cast<const wchar_t*>(pStr),
                    len,
                    stdext::make_checked_array_iterator(pDst, ArgBuffer.size())
                    );
                ArgTable[i] = pDst;
                pDst += len;
            }

            __wargv = &ArgTable[0];
            __argc = ArgTable.size();
        }
    };
}

然后,在调用 ActiveX 对象上的任何方法之前,从 C# 应用程序中调用新函数,如下所示:

ManagedCpp.Class1.PassCommandLine(new[] { "myArg1", "myArg2" });

这通过替换命令行参数的 C 运行时全局导出来工作。 ParseCommandLine() 引用的相同全局变量。你可以在这里阅读更多关于它们的信息:https://msdn.microsoft.com/en-us/library/dn727674.aspx

【讨论】:

    猜你喜欢
    • 2017-06-06
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2017-10-22
    相关资源
    最近更新 更多