2016-11-15 45 views
1

我想在ASP.NET代码隐藏DLL中使用一块Windows 10特定的UWP API(特别是Windows.Graphics.Printing3D的东西)。有没有办法做到这一点?ASP.NET中的UWP API

回答

0

在寻找仅用于.NET的解决方案时,我发现了一种适度干净的方式 - 一种Win32/64 C++ DLL,它将使用UWP API并提供基于COM或P/Invoke的接口。净。

创建一个常规的Win32 DLL。为.NET构建一个接口来消费 - 导出函数或对象,具体取决于。在我的情况下,一个导出的函数将会执行。在该项目中的C/C++设置,做如下修改:

  • 在常规下,设置Consume Windows Runtime ExtensionsYes。在常规
  • ,设置Additional #using Directories到:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcpackages;C:\Program Files (x86)\Windows Kits\10\UnionMetadata(假定的Visual Studio 2015年)
  • 在代码生成,设置Enable Minimal RebuildNo(这仅仅是用于调试,而不是发布)。

然后实例和在通常的C++/CX方式使用UWP部件在DLL,就像您在一个商店应用,经由using namespace Windows::...ref new

在这种方法中,你失去了位不可知性;非托管DLL不能是“任何CPU”。你赢了一些,你输了一些。另外,如果没有系统上的Visual C++可再发行组件包,该站点将不会运行。另一方面,它可能比.NET应用运行得更快;较少的管理/本地边界交叉口。

灵感:"Using C++/CX in Desktop apps" by Pavel Y.

+0

这似乎并没有对2017年VS有关工作的任何人都可以帮助吗? –

+0

请求一个单独的问题。 StackOverflow不是一个论坛,没有人会回答评论。 –

0

打开项目文件作为XML,并粘贴在第一<PropertyGroup>以下行:

<TargetPlatformVersion>10.0</TargetPlatformVersion> 

一旦你做到这一点,添加引用对话框将包括UWP库和文件类型选项“浏览...“对话框将包含.winmd。

加载项目,做添加引用/浏览,找到C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd,添加。

托管程序集System.Runtime.WindowsRuntime(例如IBuffer.AsStream())中有一些有用的扩展方法,但由于某种原因,它未在“程序集”下列出。要引用它,你需要直接编辑项目文件,并根据第一<ItemGroup>,添加以下内容:

<Reference Include="System.Runtime.WindowsRuntime" /> 

不同的是引导各国,你不需要编译目标更改为x86或64;任何CPU都可以。

最后,专门针对ASP.NET场景,您必须将当前AppDomainLoaderOptimization策略更改为SingleDomain。这样做,最快捷的方式是通过滥用的AppDomain的私有方法:

AppDomain ad = AppDomain.CurrentDomain; 
MethodInfo mi = ad.GetType().GetMethod("SetupLoaderOptimization", BindingFlags.Instance | BindingFlags.NonPublic); 
mi.Invoke(ad, new object[] { LoaderOptimization.SingleDomain }); 

一个很好的做到这一点会在应用程序启动代码。

一个稍微不危险的方法将涉及创建一个新的AppDomain,它将继承当前的所有设置属性,但LoaderOptimization将设置为SingleDomain,并在该域中运行UWP相关代码。像这样:

AppDomain CreateUnsharingDomain() 
{ 
    AppDomain cad = AppDomain.CurrentDomain; 
    AppDomainSetup cads = cad.SetupInformation; 
    return AppDomain.CreateDomain("Dummy", cad.Evidence, 
     new AppDomainSetup 
     { 
      ApplicationName = cads.ApplicationName, 
      ApplicationBase = cads.ApplicationBase, 
      DynamicBase = cads.DynamicBase, 
      CachePath = cads.CachePath, 
      PrivateBinPath = cads.PrivateBinPath, 
      ShadowCopyDirectories = cads.ShadowCopyDirectories, 
      ShadowCopyFiles = cads.ShadowCopyFiles, 
      ApplicationTrust = cads.ApplicationTrust, 
      LoaderOptimization = LoaderOptimization.SingleDomain 
     }); 
     //Not sure which other properties to copy... 
} 

CreateUnsharingDomain().DoCallBack(MyUWPDependentMethod); 

同样,创建一次域并缓存它的应用程序生存期也是有意义的。

在某些情况下它可能会更快;多域优化存在的原因。

灵感:"Walkthrough: Using WinRT libraries from a Windows Desktop application" by David Moore