Custom media effect in Win10 Universal App - win-universal-app

I'm developing an Universal Windows App that uses the camera and I need to create a custom effect for the camera. The app is written in C# and the effect is a C++ DLL that uses Media Foundation and an IDL to define a custom WinRT component.
I already successfully do this several times on Windows 8.1 with the following trick documented here, or here.
I now want to port this on Windows 10 UWP. I'm aware there is a known issue on Windows 10 which make the compiler fail with the error "Failed to load a dependency file. Windows.winmd" (see here). But even with that fix, I'm not able to successfully build the component.
Here is the IDL:
import "Windows.Media.idl";
#include <sdkddkver.h>
namespace MyEffect
{
[version(NTDDI_WIN10), activatable(NTDDI_WIN10)]
runtimeclass MyEffect
{
[default] interface Windows.Media.IMediaExtension;
}
}
The MIDL command line (formatted for better readability):
/env win32 /h "MyEffect_h.h" /W1 /char signed /enum_class
/tlb "$(OutDir)\MyEffect.tlb" /ns_prefix
/metadata_dir "$(WindowsSDK_MetadataFoundationPath)"
/nologo /winrt
/winmd "$(OutDir)\MyEffect.winmd"
This command succeeds. Then I add the following custom build step:
mdmerge -metadata_dir “<metadata_dir>”
-i “$(OutDir).”
-o “$(OutDir)merged”
-partial
-v
and this command fails always with different errors according to the following :
If I put $(WindowsSDK_MetadataFoundationPath), which resolves to c:\Program Files (x86)\Windows Kits\10\References\windows.foundation.foundationcontract\1.0.0.0, or $(WindowsSDK_MetadataPath), which resolves to c:\Program Files (x86)\Windows Kits\10\References it returns the error:
MDMERGE : error MDM2002: The type "Windows.Media.IMediaExtension" defined in file <...>\MyEffect.winmd was referenced by type MyEffect.MyEffect but could not be found.
If I put $(TargetPlatformSdkMetadataLocation), which resolves to c:\Program Files (x86)\Windows Kits\10\References\CommonConfiguration\Neutral, it returns the error:
MDMERGE : error MDM2012: Error 3 has occured while enumerating files in C:\Program Files (x86)\Windows Kits\10\References\CommonConfiguration\Neutral\*.winmd.
Does anyone figured out how to compile a custom Windows Media effect for UWP ?

Setting -metadata_dir to "C:\Program Files (x86)\Windows Kits\10\UnionMetadata" worked for me.

Related

Facing issue in windows SDK headers are not recursively included in Visual Studio Managed C++ project

I have created a simple Managed C++ project where I access CPoint from Atltypes.h. When compiling I am getting error 'errno.h' header not found. But I checked the project -> Properties -> VC++ Directories -> Include Directories... The header path is included.
The file errno.h is available in SDK path 'C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt'
But while compiling it is not able to pick it up. Is it due to any environment issue in my pc? Or is my visual studio settings corrupted?
After some more googling found that windows.h is key header which has all types. After adding below 2 headers in managed C++, it works fine
#include <Windows.h>
#include <msclr/marshal.h>

Visual C++ 2017 link error due to -Ot flag?

I am trying to get a Visual Studio 2017 project to link, but I'm stuck on the following linker error:
LINK : fatal error C1007: unrecognized flag '-Ot' in 'p2'
I've read questions on what the cause could be, but I couldn't come to a solution for my project.
The details are that, due to an external component we have no control over (component A), this Visual Studio 2017 project is forced to use the v14.13 version of the C++ toolchain, i.e. not the latest one (v14.14). However, the latest release of another external precompiled static lib we have no control over either (component B), is built with the v14.14 version (I checked via a dumpbin extract of the debug version of the lib). Switching my project over to the v14.14 toolchain indeed makes the link error go away on component B, but this unfortunately isn't a solution for me due to component A. Taking an earlier version of component B isn't desirable either, since we need the functionality in the latest release...
However, what strikes me, is that the /Ot ("optimize for speed") flag has been around since the middle ages... Why wouldn't v14.13 recognize it? Or is it just an (awkwardly manifested) matter of a mismatched obj file layout due to the version differences? And, probably related, what does the 'p2' stand for anyway?
Update
I've checked the linker output by using the /verbose flag, and all seems normal (3600 lines of Searching <lib>, Found <function>, Referenced in <obj> and Loaded <lib>).
Right up until the end that is, where I get the following 6 lines:
1> Searching C:\PathToExternalLib\TheirStatic.lib:
1> Found UsedFunctionName
1> Referenced in MyOwnStatic.lib(MyOwnCompileUnit.obj)
1>LINK : fatal error C1007: unrecognized flag '-Ot' in 'p2'
1>LINK : fatal error LNK1257: code generation failed
1>Done building project "MyProject.vcxproj" -- FAILED.
And that's that.
When visiting the command line setting of the link properties of the project, the only thing listed is (broken up in separate lines for convenience):
/OUT:"MyProject.dll"
/MANIFEST
/NXCOMPAT
/PDB:"MyProject.pdb"
/DYNAMICBASE "C:\PathToMyStatic.lib"
/IMPLIB:"MyProject.lib"
/DLL
/MACHINE:X64
/PGD:"MyProject.pgd"
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"MyProject.prm.intermediate.manifest"
/ERRORREPORT:PROMPT
/NOLOGO
/LIBPATH:"C:\PathToExternalStaticLib"
/LIBPATH:"C:\PathToAnotherExternalStaticLib"
/TLBID:1
So no trace of any -Ot flag there as well...?
I had this problem. LINK : fatal error C1007: unrecognized flag '-Ot' in 'p2'
while building a project with Visual Studio 2015.
I had to rebuild any library or sub library the project linked to which were built with Visual Studio 2017.
Once I rebuild the dependent libraries with Visual Studio 2015 the first project was able to link against them.
project
--------\
---------lib1(unable to rebuild lib1 until its dependencies were also rebuilt with VS2015
--------------\lib_linked_by_lib1_which_was_build_with_VS2017_and_had_to_be_rebuilt
--------------\another_lib_which_had_to_be_rebuilt_for_lib1_with_VS2015
--------\lib2
--------\lib3

Compiling C++/CX on the command line

I get the linker error fatal error C1107: could not find assembly 'platform.winmd': please specify the assembly search path using /AI or by setting the LIBPATH environment variable when I try to compile a C++/CX program on the command line.
The error is the same after I followed the instructions on this page: https://msdn.microsoft.com/en-us/library/dn769142.aspx (to summarize: run cl /ZW /EHsc source.cpp from the Developer Command Prompt for VS2015)
I also tried running vcvarsall.bat x86 store from the Developer Command Prompt for VS2015 but I still get the same error (the same error also happens when running vcvarsall.bat x86 store from a plain command prompt).
UPDATE: Apparently this bug has been fixed in VS2015 Update 1, I have not been able to test myself yet though.
As it turns out some command line parameters are missing from the documentation mentioned in the question, here is the full command line required to compile a small program:
cl /ZW
/ZW:nostdlib
/D WINAPI_FAMILY=WINAPI_FAMILY_APP
/D __WRL_NO_DEFAULT_LIB__
/Gm-
/EHsc
/MDd
/FU"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\store\references\platform.winmd"
/FU"C:\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.FoundationContract\1.0.0.0\Windows.Foundation.FoundationContract.winmd"
/FU"C:\Program Files (x86)\Windows Kits\10\References\Windows.Foundation.UniversalApiContract\1.0.0.0\Windows.Foundation.UniversalApiContract.winmd"
smurf.cpp
/link /SUBSYSTEM:CONSOLE
Where smurf.cpp contains:
using namespace Platform;
int main(Platform::Array<Platform::String^>^ args)
{
Platform::Details::Console::WriteLine("This is a C++/CX program.");
}
Will successfully print:
C:\Users\Mikael>smurf.exe
This is a C++/CX program.

MSBuild F# project with AssemblyInfo.fs file. Error during CoreCompile with fsc.exe

I have problem with building my solution by MSBuild.
In my solution I have the F# projects to which I have added the AssemblyInfo.fs files, such file looks as follows:
namespace namespaceName
open System.Reflection
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[<assembly: AssemblyTitle("assemblyName")>]
[<assembly: AssemblyDescription("")>]
[<assembly: AssemblyConfiguration("")>]
[<assembly: AssemblyCompany("")>]
[<assembly: AssemblyProduct("assemblyName")>]
[<assembly: AssemblyCopyright("Copyright © 2013")>]
[<assembly: AssemblyTrademark("")>]
[<assembly: AssemblyCulture("")>]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[<assembly: ComVisible(false)>]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[<assembly: Guid("9b60cdeb-57b8-4e08-b713-1be614a449cd")>]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the ‘*’ as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[<assembly: AssemblyVersion("1.0.0.0")>]
[<assembly: AssemblyFileVersion("1.0.0.0")>]
()
When I compile my solution in Visual Studio 2012 I do not have any problems. All assemblies are build with a nice information about version.
The problem is with the TFS Builds (I have the TFS 2012). The build of my solution always fails. The error origins in the CoreCompile fsc.exe step and it is about the AssemblyInfo.fs file:
Project "D:\path\projectMaster.csproj" (40) is building "D:\path\projectName.fsproj" (41) on node 1 (default targets).
PrepareForBuild:
Creating directory "obj\Release\".
Creating directory "bin\Release\".
GenerateTargetFrameworkMonikerAttribute:
Skipping target "GenerateTargetFrameworkMonikerAttribute" because all output files are up-to-date with respect to the input files.
CoreCompile:
C:\Program Files (x86)\Microsoft SDKs\F#\3.0\Framework\v4.0\fsc.exe -o:obj\Release\projectName.dll --debug:pdbonly --noframework --define:TRACE --doc:bin\Release\projectName.XML --optimize+ -r:D:\path\r1.dll -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\FSharp\3.0\Runtime\v4.0\FSharp.Core.dll" -r:D:\path\r2.dll -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Numerics.dll" --target:library --warn:3 --warnaserror:76 --fullpaths --flaterrors --highentropyva- "C:\Users\userName\AppData\Local\Temp\.NETFramework,Version=v4.0.AssemblyAttributes.fs" folder1\file1.fs folder1\file2.fs folder2\file1.fs
D:\path\projectName\AssemblyInfo.fs(37,10): error FS0010: Unexpected symbol ':' in expression. Expected ']' or other token. [D:\path\projectName\projectName.fsproj]
D:\path\projectName\AssemblyInfo.fs(37,1): error FS0598: Unmatched '[' [D:\path\projectName\projectName.fsproj]
D:\path\projectName\AssemblyInfo.fs(40,1): error FS0010: Incomplete structured construct at or before this point in implementation file [D:\path\projectName\projectName.fsproj]
Done Building Project "D:\path\projectName\projectName.fsproj" (default targets) -- FAILED.
I have no idea why the fsc.exe in MSBuild have problem with my AssemblyInfo.fs files.
What is more strange, when I use the "Developer Command Prompt for VS2012" and I execute exactly the same MSBuild or fsc.exe commands everything goes fine. I do not have any errors. So it seems that the TFS Build have some strange problems which I am not able to reproduce on my machines even if I run the same commands.
Thank you for any help!

OpenNI 2 and Visual Studio 2012

I just downloaded OpenNI 2 SDK (www.openni.org) and I am trying to setup a project in Visual Studio 2012.
What I did:
Create a new C++ Win32 Console Application Project
Go to Project>MyProject Properties and, in Configuration Properties>VC++ Directories...
Added C:\Program Files (x86)\OpenNI2\Redist\; to Executable Directories
Added C:\Program Files (x86)\OpenNI2\Include\; to Include Directories
Added C:\Program Files (x86)\OpenNI2\Redist\; to Reference Directories
Added C:\Program Files (x86)\OpenNI2\Lib\; to Library Directories
But when I try to build I have the following unresolved symbol error (where ConsoleApplication1 is my project's name)
Error 1 error LNK2019: unresolved external symbol
__imp__oniInitialize referenced in function
"public: static enum openni::Status __cdecl openni::OpenNI::initialize(void)"
(?initialize#OpenNI#openni##SA?AW4Status#2#XZ)
c:\Users\MyPC\documents\visual studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.obj
ConsoleApplication1
I know this linking error is saying that the linker can't find some libraries but I thought what I just did was enough.
I also tried the 64 bit version, creating a 64 bit project, but I have the same errors.
I couldn't find satisfying documentation on this topic.
I'm sure I'm missing something silly. Can you please give some advice on this?
Also you should do the below steps:
0-In the C/C++ section, under the "General" node, select
"Additional Include Directories"
and add
"$(OPENNI2_INCLUDE)" (if you use the 32-bit version) or
"$(OPENNI2_INCLUDE64)" (if you use the 64-bit version).
These are environment variables that point to the location of the OpenNI Include directory. (The defaults are :
C:\Program Files\OpenNI2\Include or
C:\Program Files (x86)\OpenNI2\Include)
1-In the Linker section, under the "General" node, select
"Additional Library Directories"
and add
"$(OPENNI2_LIB)" (if you use the 32-bit version) or
"$(OPENNI2_LIB64)" (if you use the 64-bit version).
These are environment variables that point to the location of the OpenNI Lib directory. (The defaults are:
C:\Program Files\OpenNI2\Lib or
C:\Program Files (x86)\OpenNI2\Lib)
2-In the Linker section, under the input node, select
"Additional Dependencies"
and add
OpenNI2.lib or OpenNI2.lib
3-Ensure that you add the Additional Include and Library directories to both your Release and Debug configurations.
4-Copy all the files from OpenNI's redist directory (see environment variable "$(OPENNI2_REDIST)" or "$(OPENNI2_REDIST64)") to your working directory. (The defaults are
C:\Program Files\OpenNI2\Redist or
C:\Program Files (x86)\OpenNI2\Redist).
Be aware that when you run from command line, the working directory is the directory where the executable can be found, and where you run from Visual Studio the default directory is where the project file (.vcproj, .vcxproj) can be found.
you also need to point to the actual library file: openni2.lib
If you add all of options (Include, Lib, ...) to your project setting and again get this error, maybe your project platform is Win32 and you want to use OpenNI x64
In this case, you must change the platform to x64 (Project properties at the top of the page)
If you don't have x64 option, make a new one ;)

Resources