C# 将命令行参数传递给WPF项目中的COM组件

C# 将命令行参数传递给WPF项目中的COM组件,c#,c++,wpf,xaml,mfc,C#,C++,Wpf,Xaml,Mfc,下面是设置: 使用xaml进行布局的C#WPF主项目 我们有一个古老的MFCActix/COM组件,可以使用 CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); 获取命令行参数并基于它们进行操作。无法更改此旧项目:( 用于包装COM组件的Windows窗体类库项目 组件被添加到xaml视图中,如下所示: var host = new WindowsFormsHost(); var activeX = new Viewer(); host

下面是设置:

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

  • 我们有一个古老的MFCActix/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
#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();
        }
    };
}
ManagedCpp.Class1.PassCommandLine(new[] { "myArg1", "myArg2" });
如何传递COM组件在执行其
ParseCommandLine(cmdInfo);
时将拾取的“命令行参数”

更新:

我的winform使用:私有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();
    }

只要你做了那么疯狂的事……你就可以:

在您的解决方案中添加一个新的C++/CLI项目:VisualC++ + > CLR-类库。< /P> 然后向C++/CLI类添加如下函数:

var host = new WindowsFormsHost();
var activeX = new Viewer();
host.Child = activeX;
var grid = new Grid();            
grid.Children.Add(host);
Content = grid
#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();
        }
    };
}
ManagedCpp.Class1.PassCommandLine(new[] { "myArg1", "myArg2" });

这是通过替换命令行参数的C-runtime全局导出来实现的。与ParseCommandLine()引用的全局变量相同。您可以在此处阅读有关它们的更多信息:

只要您正在做一些疯狂的事情……您可以:

在您的解决方案中添加一个新的C++/CLI项目:VisualC++ + > CLR-类库。< /P> 然后向C++/CLI类添加如下函数:

var host = new WindowsFormsHost();
var activeX = new Viewer();
host.Child = activeX;
var grid = new Grid();            
grid.Children.Add(host);
Content = grid
#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();
        }
    };
}
ManagedCpp.Class1.PassCommandLine(new[] { "myArg1", "myArg2" });

这是通过替换命令行参数的C-runtime全局导出来实现的参考资料。你可以在这里阅读更多关于它们的信息:

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