Screen record a single window - c#

I'm looking for a SDK, plugin or code that will videorecord a specific window (hwnd).
If possible in C# or Java. Does anyone know if this exists? I've been googling, but haven't come across anything.

Install Microsoft Expression Encoder 4 with Service Pack 2 (SP2).
Here's a sample program to use it. A fuller sample comes with the SDK, which is included in the download.
using System;
using System.Drawing;
using Microsoft.Expression.Encoder.ScreenCapture;
// Added references to:
// Microsoft.Expression.Encoder
// Microsoft.Expression.Encoder.Types
// Microsoft.Expression.Encoder.Utilities
// WindowsBase
// System.Drawing (for Rectangle)
namespace scrcap
{
class Program
{
static void Main(string[] args)
{
ScreenCaptureJob job = new ScreenCaptureJob();
// You can capture a window by setting its coordinates here
job.CaptureRectangle = new Rectangle(100, 100, 200, 200);
// Include the mouse pointer in the captured video
job.CaptureMouseCursor = true;
// Output file; you can transcode the xesc file to something else later.
// Note that this silently does nothing if the file already exists.
job.OutputScreenCaptureFileName = #"C:\Users\arx\scrcap\capture.xesc";
// Do some capture
job.Start();
// Wait for a keypress
Console.ReadKey();
// And stop
job.Stop();
}
}
}

Related

C# I want to know how to .Add () the same image to the Magick ++ MagickImageCollection class

Although it is the /// comment part internal code of the presentation code
I'm inserting the same image using the .Add () method of the ImageMagick.MagickImageCollection (); class, but when I insert the second one I get the following exception,
but I insert the same image Need to reload again? I don't want to do that because it takes a lot of processing time.
Exception
System.InvalidOperationException: 'Not allowed to add the same image to the collection.'
Reference site
https://github.com/dlemstra/Magick.NET/blob/main/docs/ConvertPDF.md
Environment
OS: Windows10
IDE: Visual stuido 2022
Language: C#
API: .Net 6.0
Library: Magick ++, Ghostscript
using System;
public class Program
{
public static void Main()
{
ImageMagick.MagickImage img = new ImageMagick.MagickImage("input.HEIC");
ImageMagick.MagickImageCollection images = new ImageMagick.MagickImageCollection();
images.Add(img);
/////////////////////////////////////
images.Add(img);
/////////////////////////////////////
images.Add(img);
images.Add(img);
images.Add(img);
images.Write("output.pdf");
img.Dispose();
images.Dispose();
Console.WriteLine("終了");
Console.ReadKey();
}
}
You can add the second image like this:
var img1 = new ImageMagick.MagickImage(img); ;
Then add img1
images.Add(img1);

Image dimensions getting corrupted using ImageResizer with Azure function app

I have a azure function app with one input and two outputs. In this case whenever an image is uploaded to a container: originals, the function app will be triggered which will generate two thumbnail images.
I developed the following function app using VS2017 and deployed to Azure portal.
Code:
using ImageResizer;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using System;
using System.Collections.Generic;
using System.IO;
namespace FunctionApp1
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run(
[BlobTrigger("originals/{name}", Connection = "xxxxxxx")]Stream image,
[Blob("thumbs/s-{name}", FileAccess.ReadWrite, Connection = "xxxxxxx")]Stream imageSmall,
[Blob("thumbs/m-{name}", FileAccess.ReadWrite, Connection = "xxxxxxx")]Stream imageMedium,
TraceWriter log)
{
var imageBuilder = ImageResizer.ImageBuilder.Current;
var size = imageDimensionsTable[ImageSize.Small];
imageBuilder.Build(
image, imageSmall,
new ResizeSettings(size.Item1, size.Item2, FitMode.Max, null), false);
image.Position = 0;
size = imageDimensionsTable[ImageSize.Medium];
imageBuilder.Build(
image, imageMedium,
new ResizeSettings(size.Item1, size.Item2, FitMode.Max, null), false);
}
public enum ImageSize
{
ExtraSmall, Small, Medium
}
private static Dictionary<ImageSize, Tuple<int, int>> imageDimensionsTable = new Dictionary<ImageSize, Tuple<int, int>>()
{
{ ImageSize.ExtraSmall, Tuple.Create(320, 200) },
{ ImageSize.Small, Tuple.Create(640, 400) },
{ ImageSize.Medium, Tuple.Create(800, 600) }
};
}
}
On validating it, I found that it is generating two different images as per requirement, but I see one of the file is corrupted.
CorrectImage:
CorruptedImage:
I did the validation for multiple images but see the same issue. The image with medium size configuration always gets corrupted.
Any rectifications to the above code is much helpful.
Can anyone help me to fix this issue?
Can you please check is there any other function app already in running status. In short I would like to say that check all the function apps that you have developed in this process, which is monitoring the blob storage container. I suspect that some other function app is getting triggered and causing the issue here. Please stop all the function apps and only run the required function app to see if it resolves your issue. Please let me know in case you need any further help on this.

Displaying a 2d data array from a console application

I am aware that there are already a few threads on this already created and closed (like 2-dimensional Integer array to DataGridView)
My problem is that since I have only been working with console applications, I am not aware of what I need to do in order to apply the code.
Up till now I have drag and dropped a new dataGridView and chose program.cs (where my main is) as a source. Now when I apply the code from the aforementioned link in program.cs, visualstudio is saying that dataGridView1 "does not exist in the current context". When I try to declare it beforehand, I get that the type/namespace can't be found. Any ideas?
With regard to the errors you got: All you need to do is add the namespace: using System.Windows.Forms; and also a reference to it! This works just fine for Console applications. Of course it will never show up but other than that you can make use of its abilities..
But the real question is: What do you want to achieve and why do you stick to a console application?
This is not to say that you may not have a good reason! For example it is sometimes necessary to run a service application without a display screen. This could still create output from DataGridViews or from Chart controls..
But it always helps to understand the situation fully when we answer questions here..
Here is an example that creates and fills a DataGridView DGV and then saves an image of the data to a png file.
For this to work you also need to add System.Drawing. As for Windows.Forms you need to add both the using clause and the reference:
(I have only a German VS version here; instead of the 'Aktuell' (ie 'Current') group you should search the references in the 'Framework'! The result is the same - I chose the other one becasue it is not so big on the screenshot..)
Once the references are in place..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; // <--- add namespace AND reference!!
using System.Drawing; // <--- add namespace AND reference!!
..this simple console application will compile and run:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataGridView DGV = new DataGridView();
List<string> test = new List<string>()
{ "Anna", "Bertha", "Carol", "Doreen", "Erica", "Fran", "Gisa" };
DGV.Columns.Add("No", "Number");
DGV.Columns.Add("Name", "Name");
DGV.Columns.Add("Age", "Age");
DGV.Columns["Name"].DefaultCellStyle.Font =
new Font(DGV.Font, FontStyle.Bold);
for (int i = 0; i < test.Count; i++) DGV.Rows.Add(new[]
{ (i + 1)+ "", test[i], i + 21 +""}); // cheap string array
DGV.ScrollBars = ScrollBars.None;
DGV.AllowUserToAddRows = false;
DGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
DGV.RowHeadersVisible = false;
var width = DGV.Columns.GetColumnsWidth(DataGridViewElementStates.None);
DGV.ClientSize = new Size(width,
DGV.ColumnHeadersHeight + DGV.RowCount * (DGV.Rows[0].Height) );
Bitmap bmp = new Bitmap(DGV.ClientSize.Width, DGV.ClientSize.Height);
DGV.DrawToBitmap(bmp, DGV.ClientRectangle);
bmp.Save("D:\\testDGV.png", System.Drawing.Imaging.ImageFormat.Png);
bmp.Dispose();
}
}
}

Very specific case regarding button click

I'm in a middle of process of creating utility console app to help me register to certain classes at my university. So far I've made it download website's content and frequently check for specific changes which gives me an information when the given course is full or available to be taken. Like that:
WebRequest request2 = WebRequest.Create("https://usosweb.umk.pl/kontroler.php?_action=katalog2/przedmioty/pokazPrzedmiot&prz_kod=0600-OG-ChH");
request2.Method = "GET";
WebResponse response2 = request2.GetResponse();
Stream stream2 = response2.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
string content_2 = reader2.ReadToEnd();
string drugi = getBetween(content_2, #"Stan zapełnienia grup:</b>
<b>", "</b> (zarejestrowanych/limit)");
reader2.Close();
response2.Close();
if (drugi != pierwszy)
{
Console.WriteLine("Rejestracja!");
Console.Beep(3200, 900);
System.Diagnostics.Process.Start("https://usosweb.umk.pl/kontroler.php?_action=katalog2/przedmioty/pokazPrzedmiot&prz_kod=0600-OG-ChH");
pierwszy = drugi;
}
The problem is that it still requires my full attention, as I made it only open the website with the registration buttton on and my goal is to make it actually click it automatically after the slot opens.
Few things to note:
I have to be logged on that website in order to be able to register at the course
http://i.imgur.com/DtBCG3Q.jpg <- this is how that button is coded. The chain_ function is named differently with every single refresh
http://i.imgur.com/tGX5kmy.jpg <- that is how the registration panel looks like. Ideally I want a website to open in a default browser (or somewhere with cache so I am already logged in) and automatically press that button, as it doesn't require additional confirmation.
links to one of websites at my university are included in the code above so you may have an additional look on how the buton is coded and how that case could be solved.
After all, is that even possible? Am I able to code it through? I'm using C# but some additional snippets of codes in other languagues could be put it, if that will make it easier or possible.
I think that for this kind of task automation Selenium WebDriver is the best tool
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Chrome;
namespace WEBDRIVER
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("http://www.google.com/");
IWebElement query = driver.FindElement(By.Name("q"));
query.SendKeys("banana");
query.Submit();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((d) => { return d.Title.ToLower().StartsWith("banana"); });
System.Console.WriteLine("Page title is: " + driver.Title);
driver.Quit();
}
}
}

FileVersionInfo.GetVersionInfo() incorrect in Console Application

I'm getting some serious weirdness using FileVersionInfo.GetVersionInfo() and was hoping somebody might be able to help.
The basics of the issue is that I am iterating through all the files in a folder calling GetVersionInfo() on each. There are about 300 files. This works ok for all but 2 of the files. For these DLLs I am getting comepletely incorrect info back from GetVersionInfo().
In order to eliminate all other variables, I extracted this call into a simple test app and it still got the same problem. However, if I built the test app as a Windows Application (it was a Console Application initially) then the data came back correct.
Just to clarify, the incorrect data coming back when running as a Console App is not simply null info like you would get if the file didn't contain version data. It contained reasonable data, but just the wrong data. It's as if it's reading it from a different file. I've looked for a file that contains matching version data, but can't find one.
Why is this simple call functioning differently if built as a Console Application rather than a Windows Application?
If anyone can help with this I would be very grateful.
Rgds,
Andy
-- Code Added
using System;
using System.Diagnostics;
namespace test
{
class Program
{
static void Main(string[] args)
{
string file = "C:\\ProblemFile.dll";
FileVersionInfo version = FileVersionInfo.GetVersionInfo(file);
string fileName = version.FileName;
string fileVersion = version.FileVersion;
Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion));
}
}
}
This behaviour seems weird indeed. Could it be that the Console application does not load the DLL from the same place as the WinForms application does? This would mean that GetVersionInfo uses some other API than just Win32 CreateFile (maybe going through some DLL resolver mechanism, side-by-side or whatever); remember that under the covers, version.dll will be executing your request, not the CLR itself.
Looking at FileVersionInfo through Reflector points in another direction yet:
public static unsafe FileVersionInfo GetVersionInfo(string fileName)
{
// ...
int fileVersionInfoSize = UnsafeNativeMethods.GetFileVersionInfoSize(fileName, out num);
FileVersionInfo info = new FileVersionInfo(fileName);
if (fileVersionInfoSize != 0)
{
byte[] buffer = new byte[fileVersionInfoSize];
fixed (byte* numRef = buffer)
{
IntPtr handle = new IntPtr((void*) numRef);
if (!UnsafeNativeMethods.GetFileVersionInfo(fileName, 0, fileVersionInfoSize, new HandleRef(null, handle)))
{
return info;
}
int varEntry = GetVarEntry(handle);
if (!info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(varEntry)))
{
int[] numArray = new int[] { 0x40904b0, 0x40904e4, 0x4090000 };
foreach (int num4 in numArray)
{
if ((num4 != varEntry) && info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(num4)))
{
return info;
}
}
}
}
}
return info;
}
As you can see there, some interesting dance is going on with code pages. What if the DLLs you inspected had several version information resources attached to them? Depending on the culture of the program calling into GetVersionInfo, I guess that the code page related calls could return other results?
Take the time to check the resources of the DLLs and make sure that there is only one language/code page for the version information. It might point you at the solution, I hope.
Sure the "files" you're seeing aren't . and .. ? If you iterate through all files, you'll always see entries for . (current dir) and .. (up dir). GetVersion Info might well return anything for these. You'd have to filter these entries out manually by name.
File and Assembly versions are 2 different things.
Are you sure you are not expecting the other?
Update: Tried this. Didn't work.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace test
{
class Program
{
[DllImport("COMCTL32")]
private static extern int InitCommonControls(int nExitCode);
static void Main(string[] args)
{
InitCommonControls(0);
string file = "C:\\ProblemFile.dll";
FileVersionInfo version = FileVersionInfo.GetVersionInfo(file);
string fileName = version.FileName;
string fileVersion = version.FileVersion;
Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion));
}
}
}

Categories