标签: c++-winrt

如何使用Windows运行时使用C#实现C++ API?

我正在使用一个原生C++应用程序,它有一个插件系统,它将在LoadLibrary()/ GetProcAddress().dll上调用函数.我想实现其中一个插件,在插件中我想使用持久性框架来保存/加载一个复杂的对象图到磁盘.

看起来Windows上支持最多的ORM是实体框架,这个页面说实体框架核心是最现代的风格.这个页面好像说,为了使用Entity Framework Core,你的数据模型必须用C#编写.

所以,听起来我必须从C++调用C#.幸运的是,似乎Entity Framework Core 支持通用Windows运行时,它应该使语言之间的调用变得容易.

此演示文稿似乎表示从C++与Universal Windows Runtime交互涉及创建Windows运行时组件,编译步骤可以从Windows运行时组件的.winmd文件生成粘合代码.

因此,我可以制作一个包含两个项目的Visual Studio解决方案:外部"C++ Windows桌面动态链接库"项目和内部"C#通用Windows运行时组件".

外部C++ Windows桌面动态链接库 内部C#通用Windows运行时组件

然后,文档说"引用Windows运行时组件的Windows运行时元数据(.winmd)文件,然后构建." 但是,当我在外部项目中添加引用时,当我尝试选择内部项目时出现错误,并且没有选项可以浏览以选择任意项.winmd.

尝试添加对内部项目的引用时出错

即使我进入解决方案管理器并删除除x86两个项目之外的所有平台,也会发生此错误.

这是令人惊讶的,因为这篇Windows博客帖子明确表示本机代码应该能够通过添加对该引用的引用来调用UWP代码.winmd(尽管帖子使用较旧的C++/CX语法).

如果我重新开始并使用"C++/WinRT Windows运行时组件"而不是"C++ Windows桌面动态链接库"项目,我仍然有问题.

外部C++/WinRT Windows运行时组件

如果我这样做,我可以添加参考就好了.

成功的参考

但是,当我尝试构建时,我遇到了构建失败.

1>------ Build started: Project: InnerCSharp, Configuration: Debug x86 ------
1>  InnerCSharp -> C:\Users\lithe\source\repos\EntityFrameworkInsideC++\InnerCSharp\bin\x86\Debug\InnerCSharp.winmd
2>------ Build started: Project: OuterC++WinRT, Configuration: Debug Win32 ------
2>MIDLRT Processing C:\Users\lithe\source\repos\EntityFrameworkInsideC++\OuterC++WinRT\Class.idl
2>Class.idl
2>MIDLRT Processing C:\Program Files (x86)\Windows Kits\10\Include\10.0.17134.0\winrt\winrtbase.idl
2>winrtbase.idl
2>MIDLRT Processing …
Run Code Online (Sandbox Code Playgroud)

c# visual-studio uwp c++-winrt

6
推荐指数
1
解决办法
726
查看次数

将 WinUI 与 C++ 结合使用的指南

我将尝试尽可能简洁地总结我的问题:

  • 我有一个遗留的 C++ 项目,它使用 WinAPI 创建和管理 UI 元素。我想用一个支持 OOP 并具有某种视觉设计器的更现代的框架来替换它。我打算通过用新框架逐步替换旧的基于 WinAPI 的代码来实现这一点(例如,我可以引入一个使用新框架的新弹出窗口,而 UI 的其余部分仍将使用旧的窗口过程等)
  • 我最初的计划是使用 Qt,因为它允许我方便地将 UI 代码包装在对象中,这样我就可以轻松实例化和管理对象。它还有一个设计器,可以让我创建自定义 UI 元素(包括自动布局管理)、一个 Visual Studio 扩展,总的来说,过去的经验表明 Qt 非常适合我的目的。然而,这里的用户警告我,它与 WinAPI 配合得不好,我基本上必须从头开始重建应用程序。
  • 有人建议我改用 WinUI,即 XAML 与 C++/WinRT 相结合,因为它们应该提供与我上面描述的相同的灵活性。我成功地复制了“Win32 应用程序中的主机 UWP 控件”指南的结果,但除此之外似乎没有什么有用的材料。
  • 要获得明确的答案,浏览 Microsoft 文档相当困难。目前,上面的指南让我相信我仍然会坚持使用 WinAPI,因为似乎没有一种明显的方法将 UI 代码包装在对象中,最好是那些我可以从现有基础派生的对象类(例如某种基本的 Window 对象)

我有以下环境可以使用:

  • MSVC 支持的最新 C++ 功能级别
  • 视觉工作室 2019
  • Windows 10(即我不介意是否不再与 Windows 操作系统兼容)

我需要的:

  • 关于是否可以以与使用 C++ 在 Qt 中设计 UI 代码类似的方式使用 XAML 和 C++/WinRT 的明确答案。精确的奇偶校验是不必要的,我只是想消除使用 WinAPI 管理 UI 的麻烦,实际上我必须“手动”完成所有操作

  • 如果上述情况属实,那么我在哪里可以找到工作流程各个步骤的指南?如何制作“窗口对象”,如何设计具有布局管理的窗口,如何处理 UI 事件等?

  • 如果需要在我尝试升级的旧版 WinAPI 应用程序的上下文中完成上述操作,是否同样可行?

c++ user-interface winapi c++-winrt winui

6
推荐指数
0
解决办法
4245
查看次数

从 C# 使用 C++/WinRT 组件

我有一个用 C++/CX 编写的项目(动态库),该项目由用 C# 编写的 Windows 10 通用应用程序(针对 x86 和 ARM32)使用。
我想将库重写为C++/WinRT,以便使用普通 C++。

问题 1:是否可以创建 C++/WinRT DLL 并从 C# 中使用它?
问题 2:如何设置 C++/WinRT 项目以使其能够从商店应用程序中使用?

c# windows-runtime c++-cx winrt-component c++-winrt

5
推荐指数
1
解决办法
2073
查看次数

用于更新 MFC 应用程序窗口的 C++11 线程。需要 SendMessage()、PostMessage() 吗?

在花了一些时间使用 C++/CX 和 ++/WinRT 开发简单的 UWP 应用程序后,我开始享受针对该环境进行 Windows UI 应用程序开发的一些功能。

现在必须回到更熟悉的 MFC 应用程序开发,我想将我的方法更改为类似于 UWP 应用程序开发的方法。其想法是使用异步 C++11 线程生成内容并修改 MFC UI 中显示的内容。

我想要做的主要更改是使用 C++11 线程来卸载一些耗时的任务,并使这些线程将结果传达回主 MFC UI。

我希望卸载到 C++11 线程上的一些任务(与我在 UWP 应用中使用 C++/CX 和 C++/WinRT 的异步任务使用的任务类似)是:

  • 连接到另一台计算机并与之交换数据
  • 打开数据文件并解析它以更新 UI 视图
  • 将数据文件转换为另一种格式(例如 CSV)并导出到文件
  • 读取CSV等格式的文件并将内容转换为数据文件
  • 在 UI 中执行数据文件呈现的搜索和过滤

我遇到的问题与我在 MFC 中可以有多个 GUI 线程吗?中描述的问题类似。但是,我正在寻找一种通用方法,而不是该问题中的具体进度条更新。

我一直在尝试使用 Visual Studio 模板对实验性 MFC 应用程序进行简单测试,该模板在左侧停靠有一个树控件,以在工作线程中构建树。

如果我有一个CViewTree显示树视图的 MFC 窗口,我想从 C++11 线程更新该窗口,那么我当前正在使用它::PostMessage()来请求更新停靠窗格中的树控件。

如果我将 lambda 与全局一起使用,std::thread例如以下代码:

std::thread t1;

void CClassView::FillClassView()
{
    // ::SendMessage() seems to deadlock …
Run Code Online (Sandbox Code Playgroud)

mfc multithreading c++11 c++-winrt visual-studio-2017

5
推荐指数
1
解决办法
4986
查看次数

哪些情况可以在UWP上使用CreateProcess?

我注意到 CreateProcess自版本 16299 起就是通用 Windows 平台 API的一部分。

为了测试它,我基于空白应用程序模板 (C++/WinRT) 制作了一个快速 UWP 应用程序,并连接了一个按钮事件处理程序来调用这段代码:

void StartNotepad()
{
    STARTUPINFO startupInfo;
    ZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);

    PROCESS_INFORMATION processInformation;
    ZeroMemory(&processInformation, sizeof(processInformation));

    if (!CreateProcess(
        const_cast<LPWSTR>(L"C:\\Windows\\notepad.exe"), //app name
        nullptr,
        nullptr,
        nullptr,
        FALSE,
        0,
        nullptr,
        nullptr,
        &startupInfo,
        &processInformation
    ))
    {
        OutputDebugString(L"CreateProcess failed");
        DWORD err = GetLastError();
    }
    else
    {
        WaitForSingleObject(processInformation.hProcess, INFINITE);
    }
}
Run Code Online (Sandbox Code Playgroud)

API 调用本身成功,但该过程似乎并未启动。STARTUPINFO 和 PROCESS_INFORMATION 结构确实包含新进程及其主线程的 PID 和 TID 等信息,但它没有显示在任务管理器中,也没有显示窗口(显然)。

我很确定这在某种程度上与安全有关,即 UWP 应用程序无法启动非 UWP 应用程序或类似的东西。然而,它没有在任何地方记录,这就是我在这里问的原因。

有没有人弄清楚这一点,或者微软的人可以提供更多信息吗?

uwp c++-winrt

5
推荐指数
0
解决办法
1233
查看次数

我可以在非 UWP 应用程序中使用 C++/WinRT 吗?

我刚刚听说 C++/WinRT,我很惊讶 C++ 有这个运行时,它像 .NET 一样添加了高级类包装器。但我不想将我的应用程序作为 UWP 应用程序分发。我可以在非 UWP 应用程序中使用 C++/WinRT 吗?

uwp c++-winrt

5
推荐指数
1
解决办法
1917
查看次数

C++/winRT xaml ContentDialog 示例

文档显示了这个 C# 片段:

async void DisplayDeleteFileDialog(){
    ContentDialog deleteFileDialog = new ContentDialog{
        Title = "Delete file permanently?",
        Content = "If you delete this file, you won't be able to recover it. Do you want to delete it?",
        PrimaryButtonText = "Delete",
        CloseButtonText = "Cancel"
    };

    ContentDialogResult result = await deleteFileDialog.ShowAsync();

    // Delete the file if the user clicked the primary button.
    /// Otherwise, do nothing.
    if (result == ContentDialogResult.Primary) {
         // Delete the file.
        }
    else {
         // The user clicked the …
Run Code Online (Sandbox Code Playgroud)

c++-winrt

5
推荐指数
1
解决办法
1408
查看次数

如何从 WinRT 中的接口 ID (IID) 找出类名称?

我有一个基于 BlankApp 模板的 XAML C++/WinRT 应用程序。当我构建应用程序时,我意识到我的应用程序在输出窗口中在幕后抛出了很多异常。我试图理解的例外情况如下:

Exception thrown at 0x00007FFA9EFA9149 (KernelBase.dll) in wzrd_editor.exe: WinRT originate error - 0x80040155 : 'Failed to find proxy registration for IID: {50F19C16-0A22-4D8E-A089-1EA9951657D2}.'.

我一直在做的是打破 WinRT 引发的错误并查看调用堆栈。但是我想知道如何找出错误中显示的 IID 的类名?了解这些异常的来源似乎非常有用。也许注册表中的某个地方我可以找到?

windows-runtime c++-winrt

5
推荐指数
2
解决办法
1204
查看次数

如何使用 WinRT 创建经典的 win32 应用程序窗口?

在 Win32 API 中注册窗口类、创建窗口然后通过消息泵循环保持活动状态的 C++ WinRT 等价物是什么?

我目前正在查看和阅读 WinRT 的文档,因为我想学习如何以现代 C++ 方式完成我过去在 Win32 中所做的所有事情。

到目前为止,我的经历很糟糕,我要直截了当地承认我没有得到它。

我试过了,但由于我没有在容器中运行,似乎尚未创建线程的 CoreWindow。

    int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
    {
        winrt::init_apartment(winrt::apartment_type::single_threaded);
        winrt::Windows::UI::Core::CoreWindow window = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread();

        window.Activate();

        auto dispatcher = window.Dispatcher();

        using DispatcherOptions = winrt::Windows::UI::Core::CoreProcessEventsOption;
        const DispatcherOptions options = DispatcherOptions::ProcessUntilQuit;

        dispatcher.ProcessEvents(options);
    }
Run Code Online (Sandbox Code Playgroud)

c++ windows-runtime c++-winrt

5
推荐指数
1
解决办法
2935
查看次数

在 UWP 中检索文件夹中文件大小的快速方法

我想TempState使用下面的代码来汇总应用程序文件夹中的所有文件大小,该代码工作正常。

const auto tempFolder { ApplicationData::Current().TemporaryFolder() };
int64_t size { 0 };

const QueryOptions options { CommonFolderQuery::DefaultQuery };
options.FolderDepth(FolderDepth::Shallow);
options.IndexerOption(IndexerOption::UseIndexerWhenAvailable);
options.SetPropertyPrefetch(PropertyPrefetchOptions::BasicProperties, {});

try
{
    for (auto item : co_await tempFolder.CreateFileQueryWithOptions(options).GetFilesAsync())
    {
        size += (co_await item.GetBasicPropertiesAsync()).Size();
    }

    // do something with the size
}
catch (winrt::hresult_error& err)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

目前,我的文件夹中只有不到 3000 个项目TempState,上面的代码需要 20 秒才能计算文件大小的总和。需要有一种方法来加快速度,对吗?


到目前为止我尝试过的是使用

options.IndexerOption(IndexerOption::OnlyUseIndexerAndOptimizeForIndexedProperties);
Run Code Online (Sandbox Code Playgroud)

但随后GetFilesAsync根本不返回任何文件。


可以采取什么措施来(大幅)提高性能?

uwp c++-winrt

5
推荐指数
1
解决办法
228
查看次数