I'm creating an video downloading app in C# and Universal Windows Platform. App downloads movies in three different file sets depending on the source:
.ts audio & video file
.mp4 only video file and .webm only audio file
.mp4 audio & video file
The video lenghts, on which I tested the app, range from a few seconds to several hours. Video qualities are standard YouTube qualities.
The next step is video editing. User can specify start and end trimming timestamp. Video can be saved in three different modes:
Audio & Video
Only audio
Only video
This is where the problem begins.
I can't use FFmpeg as executable, because UWP framework doesn't allow to run external app.
So I tried to use Windows.Media.Editing library. It works fine with all .mp4 audio & video files and some .ts files (but only with short videos up to an hour). Other cases throws two types of exceptions:
System.Exception
HResult=0xC00DA7FC
Message=Stream is not in a state to handle the request. Stream is not in a state to handle the request.
Source=System.Private.CoreLib
System.Exception
HResult=0xC00D6D60
Message=A valid type has not been set for this stream or a stream that it depends on. (Exception from HRESULT: 0xC00D6D60)
Source=System.Private.CoreLib
I wrote a separate question about it: Exception when rendering a video in UWP . Here is also a link to an example (In comments with sample videos, which causes an error. Link to github repository.) that downloads and tries to convert the .ts file to the .mp4 file.
So I decided to try the most complicated solution. I created a C++ DLL project and set build output destination to the new folder in the main app project folder (and set this folder to copy to build output directory). I installed an ffmpeg libraries by vcpkg and imported them in C++ project.
Here is the .cpp file:
#include "pch.h"
#include "mux.h"
extern "C" {
#include "libavformat/avformat.h"
}
int test() {
av_register_all();
return 0;
}
Here is the header:
#pragma once
#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif
extern "C" FFMPEGLIB_API int test();
And here is the C# class where is imported C++ function:
class FFmpeg
{
[DllImport(#"FFmpeg\FFmpegLib.dll")] private static extern int test();
public static void Test()
{
test();
}
}
But calling an Test() void throws an error:
System.DllNotFoundException: 'Unable to load DLL 'FFmpeg\FFmpegLib.dll' or one of its dependencies: The specified module could not be found. (Exception from HRESULT: 0x8007007E)'
There are also ffmpeg libraries (avcodec-58.dll, avformat-58.dll, avutil-56.dll, swresample-3.dll) in FFmpeg folder.
I also tried to import avformat-58.dll directly in C# (main app project) and call av_register_all() function, but it throws the same exception. I also checked if I could include "libavformat/avformat.h" in C++ UWP app, but it shows error "cannot open source file "libavformat/avformat.h"". I guess that C libraries are incompatible with UWP, but I'm not sure.
I have no more ideas. If it is not possible to use the methods I have mentioned, my question is Are there any other ways to process videos in UWP app?
I know it's obvious from the error message, but you need to verify that your program is able to locate the specified DLL file.
Check the working directory at runtime with System.IO.Directory.GetCurrentDirectory(). Is the FFmpeg\FFmpegLib.dll really there?
For simplicity, I would advice against using a subdirectory to hold the DLLs and put them at the root directory of your UWP app.
Here's a Q&A that explains how to include the DLL into your app: https://social.msdn.microsoft.com/Forums/en-US/26013e5e-3ff1-44a0-8797-0474dabd12d0/uwpincluding-dlls-in-a-uwp-application-in-visual-studio?forum=wpdevelop
It can be summarized as: add DLL files to the project root and include it into the project as a content file. This is important for when your app is distributed.
DLL's can also depend on other DLLs and will give that generic error message if any dependency is not met. You can use the Dependencies tool [https://github.com/lucasg/Dependencies] to check if FFmpegLib.dll has dependencies that are not met.
Related
I am new to PInvoke, I wanted to update my system volume using C#, I got one C++ dll and I have to just Import that DLL and use the methods to update the volume.
In C# I have written :
public const String DllName = "ChangeVolumeWindows.dll";
[DllImport(DllName, CharSet = CharSet.Auto)]
public static extern void SetSystemVolume(double newVolume, VolumeUnit vUnit);
I have put my dll into the exe path.
It is working fine for my pc , but when I package the app and send it to another machine I getting error " DLL not found "
I have observed that DLLImport is looking for path of my pc, which is not correct
For example:
I have put my dll in C:/User/ABC/Source/App/bin/debug/ChangeVolumeWindows.dll
in some another machine also it is looking for the same path instead of taking dll from C:/User/AnotherMachineUser/Source/App/bin/debug/ChangeVolumeWindows.dll
Can some one suggest where my code is going wrong.
I have tried to put my dll inside the project and the rebuild. Still I am facing the same issue.
Try this:
My.Application.Info.DirectoryPath("\folders\ChangeVolumeWindows.dll")
I want to be able to read and write to an LPT port from C#.
Tried to import inpoutx64.dll and inpout32.dll, to use these to read and write to the LPT port. But I get the following error message when I add the reference ...
A reference to 'C:\Users\User\Documents\inpoutx64.dll' could
not be added. Please ensure that the file is accessible, and that it
is a valid assembly or COM component.
Is there any other DLLer for windows 10, or is there anything i can use in Windows SDK to communicate with the LCP port ...?
I use Windows 10 64 bit, and .NET 4.5.
Since inpoutx64.dll and inpout32.dll are no valid assembly or COM components you can't import them using the project references.
You need to import the functions of the dll in code like
[DllImport("inpout32.dll", EntryPoint = "Inp32")]
private static extern int Input(int adress);
[DllImport("inpout32.dll", EntryPoint = "Out32")]
private static extern void Output(int adress, int value);
You can find a great description and more information about this import at this article.
Note that the dll needs to be in the same folder as your executable. This is easily possible by adding the dll to your project and set the build action to copy to output directory.
Above is my folder structure. I have a Cordova app and a Windows Runtime Component - IBscanUltimate. The include folder has the C# code calling into the unmanaged IBscanUltimate.dll. Class1.cs is like this:
using System;
namespace IBscanUltimate
{
public sealed class Class1
{
public static String getSDK()
{
IBscanUltimate.DLL.IBSU_SdkVersion a = new DLL.IBSU_SdkVersion();
IBscanUltimate.DLL._IBSU_GetSDKVersion(ref a);
return "SDKVersion: " + a;
}
}
The IBScanUltimateApi.cs & _IBSU_GetSDKVersion look something like this:
internal partial class DLL
{
[DllImport("IBScanUltimate.DLL")]
private static extern int IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo);
public static int _IBSU_GetSDKVersion(ref IBSU_SdkVersion pVerinfo)
{
int nRc = IBSU_STATUS_OK;
nRc = IBSU_GetSDKVersion(ref pVerinfo);
return nRc;
}
}
I have placed the DLL in many locations to see if it'll get picked up and they all have the above properties. But when I try to run my app, it says unable to locate the IBScanUltimate.DLL
This is how the output is coming:
I am not sure what is it that I am doing wrong and why the DLLImport cannot find my dll. Thank you for your help.
Exact error is:
System.DllNotFoundException: Unable to load DLL 'IBScanUltimate.DLL': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Update #1:
I have come across https://msdn.microsoft.com/en-us/library/windows/desktop/hh447159(v=vs.85).aspx This article is explaining that LoadPackagedLibrary function can be used to load the dll. I am not seeing any example on how to use this in C#.
Update #2:
Specify the search path for DllImport in .NET Mentions that SetDllDirectory or AddDllDirectory can be used. He has a code snippet for SetDllDirectory, but the argument is string[] paths. How would I specify the relative argument?
Update #3:
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
public static bool setPath(String path)
{
//Windows.Storage.
//return SetDllDirectory("ms-appx:///");
return SetDllDirectory(path);
}
I tried calling the SetDllDirectory(path) method with various locations that my app should have access to but I am keep getting "false". Few examples that I have tried:
NativeMethods.setPath(Package.Current.InstalledLocation.Path.ToString());
StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
This is where my app is installed:
C:\Users\AAA\App\hello\platforms\windows\build\windows\Debug\x64\AppX
and I can see that my DLL is there. But still I'm getting the exception that DLL cannot be found. Do I have to put something on the manifest regarding this?
Update #4:
I ran a dumpbin on the DLL and i see the below DLL in the dumpbin:
WINUSB.DLL
mfc90.dll
MSVCR90.dll
KERNEL32.dll
USER32.dll
GDI32.dll
VERSION.dll
MSVCP90.dll
SETUPAPI.dll
I guess I'd like to check on each dll above separately to see if my windows runtime can pick it? One of them could be the culprit that's not being loaded?
Update #5:
Upon seeing the answer from Peter Torr - MSFT, and googling for MFC I came across this article https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx Which states:
The MFC classes and their members cannot be used in applications that execute in the Windows Runtime.
I guess to conclude this wild hunt now. I would close this up that the library I tried to load is dependent on libraries not available for Windows Runtime.
I had this feeling because Windows form application would run but the the code converted to Windows Runtime would give the error that the DLL is not being found. Thanks to Peter for guiding in the right direction.
The DLL you are trying to load was clearly built for desktop apps (it has User, GDI, and MFC imports) and will not work as a UWP binary. I suspect also that the DLL does not have the AppContainer flag set (an option you pass to the linker). You will need to find another way to accomplish what you need (if necessary, please make any feature requests via the Windows Platform UserVoice.
I suspect that it can find your DLL just fine, but it fails to find one or more of its dependencies. Unfortunately, both of these cases result in extremely generic DllNotFoundException that mentions the DLL your try to P/Invoke to.
There is an easy way to figure out what's missing! Windows contains a feature called "loader snaps", which, when enabled, will log all the things that Windows DLL loader does for your process. That means it will also print what DLLs it fails to load. To enable it, run this in admin command prompt:
gflags.exe -i "<executableName>.exe" +sls
Where executable name is just the name of your executable without the folder. To see the output, you will also need to enable either native or mixed mode debugger. You can do that in your project properties debugging tab in Visual Studio.
You can read more about load snaps here:
https://blogs.msdn.microsoft.com/junfeng/2006/11/20/debugging-loadlibrary-failures/
I'm trying to import a library to my WCF project, the DLL was provided by Adminpaq.
i'm using the next following code:
[DllImport("MGW_SDK.dll", EntryPoint = "fInicializaSDK")]
public static extern int fInicializaSDK();
When i debug the app say the next error : Unable to load DLL The specified module could not be found.
I've ready on web that the error could be by dependece but on the SDK documentation display a list of some files that must be added to the root project i'm currently adding al of them
Some info:
Dll is build on: c++
Proyect type: c# Application service MCF
I'm using: Windows 7 ultimate x64
Any further information required please don't hesitate to ask.
You are right, usually it is related to some other library that your MGW_SDK.dll depends on. Try these:
1) Install the Microsoft Visual C++ redist (2005, 2008 or 2010, depending on which VS was used to build that dll)
2) If that does not help, try using dependency walker tool to see which files are missing (http://www.dependencywalker.com)
I hope that helps.
You must type the full and original path of the DLL, for example: #"C:\Program Files (x86)\Compacw\AdminPAQ\MGW_SDK.dll"
you must install AdminPaq and have a registered license, after that the error will dissapear
I have C++ DLL as below
#include "stdafx.h"
extern "C" __declspec(dllexport)double Add(double a, double b);
extern double Add(double a, double b)
{
return a + b;
}
n here m trying to link this DLL with my C# app
using System.Text;
using System.Runtime.InteropServices;
namespace test
{
class Program
{
[DllImport("DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern double Add(double a, double b);
static void Main(string[] args)
{
Console.WriteLine(Add(1.0, 3.0)); // error here
Console.ReadLine();
}
}
}
m getting error:
"Unable to load DLL 'DLL.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)"
please help me out ...how can i link c++ dll with c# ?
The calling convention determines how function parameters are placed on the stack prior to a function invocation, and how they are removed (caller vs. callee) when the function returns. You can find out much more about this in about a million StackOverflow questions, or goto here and read up a little.
Regarding placement of the DLL within reach of the C# (aka .NET) application you're writing, I'm afraid I cannot comment on that except to say general DLL's must be in your lib-search path (PATH in Windows) the current directory, or the kernel's home directory (generally c:\windows\system32. Do NOT copy files to system32, btw. just setup your application to "run from" the directory where your DLL is residing and you should be fine. There are exceptions to this, and configuration settings that can radically alter this, but were I you i'd stick with simple for now. Complex can always come later.
You will either need to plant the dll in the same location as the C# exe or pack the dll inside the exe. The first option is simple enough. For the second option, check out Embedding DLL's into .exe in in Visual C# 2010
you got this error because DLL.dll wasn't in your Debug/Release Folder,
as far as i know visual studio doesn't know how to copy those files to your output folder manualy.
add the dll file to your C# solution
and then on files properties set build action to content
and set copy to output directory to copy if newer this will automate the copying