C# find the length of a video file - c#

I am using the following code to find the length of a video file.
WindowsMediaPlayer windowsMediaPlayer = new WindowsMediaPlayer();
WindowsMediaPlayer player = windowsMediaPlayer;
var clip = player.newMedia(strPath);
WMPLength = $"{TimeSpan.FromSeconds(clip.duration)} ";
player.close();
The code returns what I expect but there are two problems.
One it crashes randomly. It crashes like its out of memory but while I do see memory usage go up it doesn't appear to be enough to crash the program
Two it is very slow
Am I missing something in cleaning up the code, a memory leak
or is there a better way to do this?
Thank you

First thing first: your method requires WMP installed on the computer, there are many editions without WMP installed oob.
This is an approach i am using and no problems so far (not sure why you need the media player) is it a specific requirement, extension ?
1-Install the following NuGet package, Microsoft.WindowsAPICodePack-Shell
https://www.nuget.org/packages/Microsoft.WindowsAPICodePack-Shell
2-Use the code snipet
using Microsoft.WindowsAPICodePack.Shell;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VideoLenght
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(GetVideoDuration(#"C:\videos\20190531_005611.mp4"));
Console.ReadLine();
}
public static TimeSpan GetVideoDuration(string filePath)
{
using (var shell = ShellObject.FromParsingName(filePath))
{
IShellProperty prop = shell.Properties.System.Media.Duration;
var t = (ulong)prop.ValueAsObject;
return TimeSpan.FromTicks((long)t);
}
}
}
}

Related

How do I solve: The type or namespace Windows does not exist in namespace Microsoft?

How do I solve this missing dependency? Googling around for this problem, it seems rare. I see similar ones like The type or namespace name 'Windows' does not exist in the namespace 'System' but nowhere do I see someone explain this particular message.
Log files naturally recorded by windows at locations such as C:\Windows\System32\WDI\LogFiles\BootPerfDiagLogger.etl record useful forensic security info, such as every process that ran persistently at boot.
My goal is to parse these files into some intermediary structure like XML or JSON so I can import the data to Python.
I wanted to parse Windows ETL files in Python for forensic / security data science. I thought this would be easy since there's a Python library for it but upon running that library, it doesn't work and is probably no longer maintained.
Luckily I found a Microsoft dev blog on parsing ETL files with the same classes Windows exposes to allow Windows Performance Analyzer to do it.
The example code shown was like:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Windows.EventTracing;
using Microsoft.Windows.EventTracing.Disk;
using Microsoft.Windows.EventTracing.Processes;
class FileOperation
{
public IProcess IssuingProcess;
public string Operation;
public string Path;
public long Size;
public decimal Duration;
}
class Program
{
public static void Main(string[] args)
{
var etlFileName = args[0];
var diskTrace = Path.GetFileNameWithoutExtension(etlFileName) + "-disk.csv";
var fileTrace = Path.GetFileNameWithoutExtension(etlFileName) + "-file.csv";
using (ITraceProcessor trace = TraceProcessor.Create(etlFileName))
{
var pendingDisk = trace.UseDiskIOData();
var pendingFile = trace.UseFileIOData();
trace.Process();
ProcessDisk(pendingDisk.Result, diskTrace);
ProcessFile(pendingFile.Result, fileTrace);
}
}
I won't include the ProcessDisk and ProcessFile classes here because those seem to be geared toward whatever debugging purpose the writer had. Rather, I'm interested in trace. Based on the methods I see called: UseDiskIOData, UseFileIOData, presumably there is a longer list of methods like that I could use to access all available data for each trace.
My immediate goal with this question is just to view what methods exist on the trace object.
So I did some research on how you look at all properties on an object in C#, and there are plenty of answers, that's probably not a problem:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Windows.EventTracing;
using Microsoft.Windows.EventTracing.Disk;
using Microsoft.Windows.EventTracing.Processes;
class Program
{
public static void Main(string[] args)
{
var etlFileName = args[0];
#var diskTrace = Path.GetFileNameWithoutExtension(etlFileName) + "-disk.csv";
#var fileTrace = Path.GetFileNameWithoutExtension(etlFileName) + "-file.csv";
using (ITraceProcessor trace = TraceProcessor.Create(etlFileName))
{
Type myType = trace.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
foreach (PropertyInfo prop in props)
{
object propValue = prop.GetValue(trace, null);
// Do something with propValue
Console.WriteLine(propValue);
}
#var pendingDisk = trace.UseDiskIOData();
#var pendingFile = trace.UseFileIOData();
#trace.Process();
#ProcessDisk(pendingDisk.Result, diskTrace);
#ProcessFile(pendingFile.Result, fileTrace);
}
}
But what I did have a problem with is this:
The type or namespace Windows does not exist in namespace Microsoft
As I said, I looked around for solutions to this and found nothing.

C# connecting (referencing) couple *.cs files

I have couple questions about referencing methods / variables between two or more *.cs files. I know that there are similar topics, but I still don't quite understand what is going on.
I'm using Visual Studio Community 2015.
So here is the problem. I have 2 files, those files are First.cs and Second.cs. They are saved in completely different, known locations on hard disc.
Inside First.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Forum
{
class First
{
static void Main(string[] args)
{
}
public int GiveMeNumber()
{
return 5;
}
}
}
Inside Second.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Forum
{
class Second
{
int number = // method from file First.cs
}
}
How do I access method GiveMeNumber() from First.cs in Second.cs as assignment for int number? How do I tell my compiler where are those files?
Thanks for any help :)
Like Alex said in his comment.
You can create a solution/project, add existing item, and browse to your first.cs and second.cs.
Mark both files with the public-keyword
for example:
namespace Forum
{
public class Second
{
int number = // method from file First.cs
}
}
Then both class can be used within each other.
So you could do
var first = new First();
var number = first.GiveMeNumber();
you probably want to do it the other way around, because I think you have a console app where your First class has a main-method.
does that help>?

TestStack.White and CCleaner

I've very new to the TestStack (White) UI Automation library and I'm having a bit of an issue in terms of "hooking" the process. I'm trying to hook CCleaner, but I keep getting
An unhandled exception of type 'TestStack.White.AutomationException'
occurred in TestStack.White.dll
Additional information: Couldn't find window with title Piriform
CCleaner in process 1156, after waiting for 30 seconds:
My current code is:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using TestStack.White;
using TestStack.White.Factory;
using TestStack.White.UIItems.Finders;
using TestStack.White.InputDevices;
using TestStack.White.UIItems.WindowItems;
namespace NightWipe
{
class Program
{
private const string ExeSourceFile = #"C:\Program Files\CCleaner\CCleaner.exe";
private static TestStack.White.Application _application;
private static TestStack.White.UIItems.WindowItems.Window _mainWindow;
static void Main(string[] args)
{
clean();
}
public static string clean()
{
var psi = new ProcessStartInfo(ExeSourceFile);
_application = TestStack.White.Application.AttachOrLaunch(psi);
_mainWindow = _application.GetWindow("Piriform CCleaner");
_mainWindow.WaitWhileBusy();
return "";
}
}
}
I thought that maybe it was the name of the process since CCleaner starts another process (not CCleaner.exe) but CCleaner64.exe as seen here, which I can assume is for 64 bit operating systems maybe? Anyway I tried names including: "CCleaner", "CCleaner64"; but this threw the same exact exception.
I'm using Inspect by Microsoft and this is what it pulls for me (large image):
Inspect's information. Any idea what I'm doing wrong here?
The problem is that CCleaner is visible as WIN32 app. So GetWindow() doesn't work. You can try this code:
public void CCleanerSample()
{
var application = Application.AttachOrLaunch(new ProcessStartInfo(#"C:\Program Files\CCleaner\CCleaner.exe"));
AutomationElement ccleanerAutomationElement = null;
Console.Write("Waiting till WIN32 app is launching");
while (ccleanerAutomationElement == null)
{
ccleanerAutomationElement = AutomationElement.RootElement.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.NameProperty, "Piriform CCleaner"));
Thread.Sleep(1000);
Console.Write(".");
}
Console.WriteLine(" Done");
var mainWindow = new Win32Window(ccleanerAutomationElement, WindowFactory.Desktop, InitializeOption.NoCache,
new WindowSession(application.ApplicationSession, InitializeOption.NoCache));
}

Synaptics SDK can't find device

I'm attempting to grab a device handle on the Synaptics Touchpad using the Synaptics SDK, specifically using methods in the SYNCTRLLib.
However, the SYNCTRL method failed to find it, returning -1.
Syn.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SYNCOMLib;
using SYNCTRLLib;
namespace TP_Test1
{
class Syn
{
SynAPICtrl SynTP_API = new SynAPICtrl();
SynDeviceCtrl SynTP_Dev = new SynDeviceCtrl();
SynPacketCtrl SynTP_Pack = new SynPacketCtrl();
int DeviceHandle;
//Constructor
public Syn ()
{
SynTP_API.Initialize();
SynTP_API.Activate();
//DeviceHandle == -1 ? Can't find device?
DeviceHandle = SynTP_API.FindDevice(new SynConnectionType(), new SynDeviceType(), 0);
//Below line causing Unhandled Exception
SynTP_Dev.Select(DeviceHandle);
SynTP_Dev.Activate();
SynTP_Dev.OnPacket += SynTP_Dev_OnPacket;
}
public void SynTP_Dev_OnPacket()
{
Console.WriteLine(SynTP_Pack.FingerState);
Console.WriteLine(SynTP_Pack.X);
Console.WriteLine(SynTP_Pack.Y);
}
}
}
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SYNCOMLib;
using SYNCTRLLib;
namespace TP_Test1
{
class Program
{
static void Main(string[] args)
{
Syn mySyn = new Syn();
mySyn.SynTP_Dev_OnPacket();
}
}
}
I see that you are using the C# wrappers for Synaptics SDK. Even though CPP code might be not trivial to you, you might want to take a look at the file Samples/ComTest.cpp. It contains some example logic in order to find devices, more specifically at lines 66-76:
// Find a device, preferentially a TouchPad or Styk.
ISynDevice *pDevice = 0;
long lHandle = -1;
if ((pAPI->FindDevice(SE_ConnectionAny, SE_DeviceTouchPad, &lHandle) &&
pAPI->FindDevice(SE_ConnectionAny, SE_DeviceStyk, &lHandle) &&
pAPI->FindDevice(SE_ConnectionAny, SE_DeviceAny, &lHandle)) ||
pAPI->CreateDevice(lHandle, &pDevice))
{
printf("Unable to find a Synaptics Device.\n");
exit(-1);
}
Also, make sure you have registered the dlls. According to the ReadSynSDK.txt file:
For certain purposes it may be necessary to register the dlls
that are provided with the SDK. This can be done with the windows regsvr32
utility.

Would you share your idea how to call python command from embedded Python.Net?

I've been played with Python.Net for a week, but I can't find any sample code to use Python.Net in embedded way although Python.Net source has several embeddeding tests. I've searched many threads from the previous emailing list (Python.Net), the results are not consistent and are clueless.
What I'm trying to do is to get result (PyObject po) from C# code after executing python command such as 'print 2+3' from python prompt via Python.Net because IronPython doesn't have compatibility with the module that I currently using.
When I executed it from nPython.exe, it prints out 5 as I expected. However, when I run this code from embedded way from C#. it returns 'null' always. Would you give me some thoughts how I can get the execution result?
Thank you,
Spark.
Enviroments:
1. Windows 2008 R2, .Net 4.0. Compiled Python.Net with Python27, UCS2 at VS2012
2. nPython.exe works fine to run 'print 2+3'
using NUnit.Framework;
using Python.Runtime;
namespace CommonTest
{
[TestFixture]
public class PythonTests
{
public PythonTests()
{
}
[Test]
public void CommonPythonTests()
{
PythonEngine.Initialize();
IntPtr gs = PythonEngine.AcquireLock();
PyObject po = PythonEngine.RunString("print 2+3");
PythonEngine.ReleaseLock(gs);
PythonEngine.Shutdown();
}
}
}
It seems like PythonEngine.RunString() doesn't work. Instead, PythonEngine.RunSimpleString() works fine.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Reflection;
using Python.Runtime;
namespace npythontest
{
public class Program
{
static void Main(string[] args)
{
string external_file = "c:\\\\temp\\\\a.py";
Console.WriteLine("Hello World!");
PythonEngine.Initialize();
IntPtr pythonLock = PythonEngine.AcquireLock();
var mod = Python.Runtime.PythonEngine.ImportModule("os.path");
var ret = mod.InvokeMethod("join", new Python.Runtime.PyString("my"), new Python.Runtime.PyString("path"));
Console.WriteLine(mod);
Console.WriteLine(ret);
PythonEngine.RunSimpleString("import os.path\n");
PythonEngine.RunSimpleString("p = os.path.join(\"other\",\"path\")\n");
PythonEngine.RunSimpleString("print p\n");
PythonEngine.RunSimpleString("print 3+2");
PythonEngine.RunSimpleString("execfile('" + external_file + "')");
PythonEngine.ReleaseLock(pythonLock);
PythonEngine.Shutdown();
}
}
}

Categories