I am trying to monitor my Wifi adapter's throughput numerically on the system tray; like so.
I figured out the static Powershell query
((Get-Counter '\\mullick1\network interface(intel[r] centrino[r] advanced-n 6205)\bytes total/sec').countersamples).cookedvalue*8/102400000*100
But how can I get the continuous feed and how do I put it on the system tray ?
I found an alternate solution in the Diskled software. But it doesn't show the actual value.
This is the script to render(update) a text at a notify icon.
Customize the "Get-NotifyIconText" function as you like.
#Requires -Version 3.0
function Get-NotifyIconText {
[DateTime]::Now.Second.ToString()
# ((Get-Counter '\\mypc\network interface(Intel[R] 82579V Gigabit Network Connection)\bytes total/sec').countersamples).cookedvalue*8/102400000*100
}
Add-Type -ReferencedAssemblies #("System.Windows.Forms"; "System.Drawing") -TypeDefinition #"
using System;
using System.Drawing;
using System.Windows.Forms;
public static class TextNotifyIcon
{
// it's difficult to call DestroyIcon() with powershell only...
[System.Runtime.InteropServices.DllImport("user32")]
private static extern bool DestroyIcon(IntPtr hIcon);
public static NotifyIcon CreateTrayIcon()
{
var notifyIcon = new NotifyIcon();
notifyIcon.Visible = true;
return notifyIcon;
}
public static void UpdateIcon(NotifyIcon notifyIcon, string text)
{
using (var b = new Bitmap(16, 16))
using (var g = Graphics.FromImage(b))
using (var font = new Font(FontFamily.GenericMonospace, 8))
{
g.DrawString(text, font, Brushes.Black, 0, 0);
var icon = b.GetHicon();
try
{
notifyIcon.Icon = Icon.FromHandle(icon);
} finally
{
DestroyIcon(icon);
}
}
}
}
"#
$icon = [TextNotifyIcon]::CreateTrayIcon()
while ($true) {
$text = Get-NotifyIconText
[TextNotifyIcon]::UpdateIcon($icon, $text)
[Threading.Thread]::Sleep(1000)
}
Related
I was looking for a Circular Picture Box for my app and I stumbled across this code (IT IS NOT MINE) and I've tried as many times as I could but I can't find any mistake. I have followed every step that was made in the tutorial for this Rounded Picture Box so it can't be a miscopy because it was working perfectly in the tutorial.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace New_Radio_Barcelona.Controls
{
class RashiCircularPictureBox : PictureBox
{
private int border = 2;
private Color colorBorder = Color.RoyalBlue;
private Color colorBorder2 = Color.HotPink;
private DashStyle borderstyle = DashStyle.Solid;
private DashCap borderCap = DashCap.Flat;
private float gradiant = 50f;
public RashiCircularPictureBox()
{
this.Size = new Size(95, 95);
this.SizeMode = PictureBoxSizeMode.StretchImage;
}
public int Border
{
get
{
return border;
}
set
{
border = value;
this.Invalidate();
}
}
public Color ColorBorder
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
this.Invalidate();
}
}
public Color ColorBorder2
{
get
{
return colorBorder2;
}
set
{
colorBorder2 = value;
this.Invalidate();
}
}
public DashStyle Borderstyle
{
get
{
return borderstyle;
}
set
{
borderstyle = value;
this.Invalidate();
}
}
public DashCap BorderCap
{
get
{
return borderCap;
}
set
{
borderCap = value;
this.Invalidate();
}
}
public float Gradiant
{
get
{
return gradiant;
}
set
{
gradiant = value;
this.Invalidate();
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Size = new Size(this.Width, this.Width);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
var graphic = pe.Graphics;
var rect = Rectangle.Inflate(this.ClientRectangle, -1, -1);
var rectborder = Rectangle.Inflate(rect, -border, -border);
var size = border > 0 ? border * 3 : 1;
using (var bordercolorG = new LinearGradientBrush(rectborder, colorBorder, colorBorder2, gradiant))
using (var path = new GraphicsPath())
using (var pen = new Pen(this.Parent.BackColor, border))
using (var penborder = new Pen(bordercolorG, size))
{
graphic.SmoothingMode = SmoothingMode.AntiAlias;
penborder.DashStyle = borderstyle;
penborder.DashCap = borderCap;
path.AddEllipse(rect);
this.Region = new Region(path);
graphic.DrawEllipse(pen, rect);
if (border > 0)
{
graphic.DrawEllipse(penborder, rectborder);
}
}
}
}
}
I compile the project and then try to add it to the Design tab as shown in the tutorial. It says it could not be loaded. I was trying to understand what is not working properly but I still do not find the mistake. Some help plis?
Another aspect to take into consideration is the fact that in class RashiCircularPictureBox : PictureBox puts 1 reference above the code and in public RashiCircularPictureBox() it says 0 references. It may be for this but I'm no expert on Classes and I'm stuck in this stupidity. if anyone could clear my mind about this issue I would be so grateful about it
The designer in most versions of Visual Studio up until recently has been a 32-bit process. So if the control was built as 64-bit, it wouldn’t be able to load it at design-time, but VS would still be able to create 64-bit applications that can use the 64-bit control at runtime.
This means if you build your control as 32-bit or AnyCPU, it should solve the design-time loading problem.
The release notes of Visual Studio 2022 version 17.0.0 state that “devenv.exe is now 64-bit only”. I haven’t tried this myself, but it probably means you can now use 64-bit controls at design time with the newer versions of VS.
In all cases, AnyCPU should work.
The truth is that I have a simple tool to let the game auto run on my android phone. I want to collect the some performance data like Profiler provides, memory, draw calls, each mem allocate on each function and so on. So is there any api or tool to reach that?
As you already noticed, you can't save from the Profiler more than 300 frames of data.
The only way to save a stream of profiling data, is to write a class and attach the script to every game object in the scene.
using UnityEngine;
using UnityEngine.Profiling;
using System.Collections;
public class ProfilerDataLogger : MonoBehaviour
{
int frameCount = 0;
void Update()
{
if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.L))
{
StopAllCoroutines();
frameCount = 0;
StartCoroutine(DataLogger());
}
}
IEnumerator DataLogger()
{
while (true)
{
string filepath = Application.persistentDataPath + "/profilerData" + frameCount + ".log";
Profiler.logFile = filepath;
Profiler.enableBinaryLog = true;
Profiler.enabled = true;
for (int i = 0; i < 300; i++)
{
yield return new WaitForEndOfFrame();
if (!Profiler.enabled)
Profiler.enabled = true;
}
frameCount++;
}
}
}
Then, you can load the log files (each containing 300 frames of data) in the Profiler, or you can write a class in order to execute the loading from the Editor.
Update: I've developed my own PowerShell solution (in the answers), but I'd still like to know if anyone knows of a NuGet package that mimics the behavior of the abandoned StudioShell project.
I'm trying to use EnvDTE to make some problematic settings persistent (no matter what future devs do) in my Visual Studio 2015 solutions/projects using only pre/post-build scripts, NuGet packages, or some built-in feature of VS. (I'll refer to these settings/configuration changes as "tweaks" from here on)
The end goals are:
No external tools/extensions required - Whatever I use to make these changes should be a standard part of Visual Studio 2015 and/or should be portable with the solution, or it should be reasonable to expect it to be part of recent Windows operating systems (Windows 7+).
In other words, future developers who inherit my work should be able to pull the solution from source control and build it without needing to install VS extension "X", make change "Y" in their build environment, or change "Z" in their user specific project settings.
Discoverable - The component/tool/method used to make the tweaks should be exposed somewhere in the Visual Studio interface without digging further than the solution tree (including context menus, project properties, etc.) - so the automated tweaks can be altered or disabled without too much digging.
I don't mind the GUI element just being a link to some code. I expect the future devs can figure out the code, but they need to be able to easily discover that this code is responsible for maintaining the EnvDTE tweaks.
For example, custom MSBuild tasks could potentially be considered a "built-in" solution, but those custom tasks are completely hidden to the average developer in my office. (Pre/Post build events are borderline hidden too, but at least they are in the GUI where devs can run across those by accident on occasion)
So, does anyone know of a NuGet package (StudioShell may have been perfect, but it looks like that project has been abandoned and there's no support for VS2015) or some other solution that would give me access to a DTE object bound to the current instance of VS from within a pre/post-build process? Or better yet, a method of using EnvDTE to tweak things when the solution/project is loaded?
Specific tweaks
The specific settings I'm trying to tweak from EnvDTE are not really relevant in my opinion, but since I know someone will ask, here are the tweaks I'm currently trying to get in place during solution/project load or at least before the build/debug process starts.
Set the startup project - I'm surprised this bug still plagues me, but despite having already set the startup project in the solution, inevitably some other dev pulls down my solution and ends up with the wrong project set as the startup project which messes with the dependencies/build order and breaks the build.
Configure user/environment specific project settings (ie. settings stored in <project>.user files) that are known to be generic enough for all build environments to use.
More specifically, I want to set the Project Properties -> Web -> Start Action configuration items in a web project. For normal web projects I understand why these settings are user specific because who knows what browsers the dev might have. But, I have a web hosted WCF service with test scripts nested under the project directory - so project debugging should always be able to be done running those scripts using relative paths known at build time even when the path to the solution/project changes between environments.
Here's the post-build event PowerShell solution I've come up with (a workaround for users running in a Restricted execution policy is at the end of this answer).
1) Create a PowerShell script containing the following:
Param(
[Parameter(Mandatory=$True,Position=1)]
[string] $projPath,
[Parameter(Mandatory=$True,Position=2)]
[string] $debugScriptPath
)
# Setup new data types and .NET classes to get EnvDTE from a specific process
Add-Type -TypeDefinition #"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text.RegularExpressions;
public static class NTDLL
{
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebBaseAddress;
public IntPtr Reserved2_0;
public IntPtr Reserved2_1;
public IntPtr UniqueProcessId;
public UIntPtr ParentUniqueProcessId;
}
public static UInt32 GetParentProcessID(IntPtr handle)
{
PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
Int32 returnLength;
UInt32 status = NtQueryInformationProcess(handle, IntPtr.Zero, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
return 0;
return pbi.ParentUniqueProcessId.ToUInt32();
}
[DllImport("ntdll.dll")]
private static extern UInt32 NtQueryInformationProcess(IntPtr processHandle, IntPtr processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, Int32 processInformationLength, out Int32 returnLength);
}
public static class OLE32
{
[DllImport("ole32.dll")]
public static extern Int32 CreateBindCtx(UInt32 reserved, out IBindCtx ppbc);
}
public class VisualStudioProcBinder
{
public static Object GetDTE(int processId)
{
Regex VSMonikerNameRegex = new Regex(#"!?VisualStudio\.DTE([\.\d]+)?:" + processId);
object runningObject = null;
IBindCtx bindCtx = null;
IRunningObjectTable rot = null;
IEnumMoniker enumMonikers = null;
try
{
Marshal.ThrowExceptionForHR(OLE32.CreateBindCtx(0, out bindCtx));
bindCtx.GetRunningObjectTable(out rot);
rot.EnumRunning(out enumMonikers);
IMoniker[] moniker = new IMoniker[1];
IntPtr numberFetched = IntPtr.Zero;
while (enumMonikers.Next(1, moniker, numberFetched) == 0)
{
IMoniker runningObjectMoniker = moniker[0];
string name = null;
try
{
if (runningObjectMoniker != null)
runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
}
catch (UnauthorizedAccessException)
{
// Do nothing, there is something in the ROT that we do not have access to.
}
if (!string.IsNullOrEmpty(name) && VSMonikerNameRegex.IsMatch(name))
{
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
break;
}
}
}
finally
{
if (enumMonikers != null)
Marshal.ReleaseComObject(enumMonikers);
if (rot != null)
Marshal.ReleaseComObject(rot);
if (bindCtx != null)
Marshal.ReleaseComObject(bindCtx);
}
return runningObject;
}
}
"#
# Get the devenv.exe process that started this pre/post-build event
[Diagnostics.Process] $dteProc = [Diagnostics.Process]::GetCurrentProcess();
while ($dteProc -and $dteProc.MainModule.ModuleName -ne 'devenv.exe')
{
#Write-Host "$(${dteProc}.Id) = $(${dteProc}.MainModule.ModuleName)";
try { $dteProc = [Diagnostics.Process]::GetProcessById([NTDLL]::GetParentProcessID($dteProc.Handle)); }
catch { $_; $dteProc = $null; }
}
# Get dteCOMObject using the parent process we just located
$dteCOMObject = [VisualStudioProcBinder]::GetDTE($dteProc.Id);
# Get the project directory
$projDir = Split-Path $projPath -Parent;
# If the script path does not exist on its own - try using it relative to the project directory
if (!(Test-Path $debugScriptPath)) {
$debugScriptPath = "${projDir}\${debugScriptPath}";
}
#####################################################
# Finally, tweak the project
#####################################################
if ($dteCOMObject) {
# Get the project reference from DTE
$dteProject = $dteCOMObject.Solution.Projects | ? { $_.FileName -eq $projPath } | Select-Object -First 1;
# Set this project as the startup project
$startupProj = $dteCOMObject.Solution.Properties["StartupProject"].Value;
if ($startupProj -ne $dteProject.Name) {
$dteCOMObject.Solution.Properties["StartupProject"].Value = $dteProject.Name;
}
# Get the external debug program and arguments currently in use
$debugProg = $dteProject.Properties['WebApplication.StartExternalProgram'].Value;
$debugArgs = $dteProject.Properties['WebApplication.StartCmdLineArguments'].Value;
# If an external debug program is not set, or it is set to cmd.exe /C "<file path>"
# and "file path" points to a file that doesn't exist (ie. project path has changed)
# then correct the program/args
if (!$debugProg -or ($debugProg -eq $env:ComSpec -and $debugArgs -match '^\s*/C\s+("?)([^"]+)\1$'-and !(Test-Path $Matches[2]))) {
if (!$debugProg) { $dteProject.Properties['WebApplication.DebugStartAction'].Value = 2; } # 2 = run external program
$dteProject.Properties['WebApplication.StartExternalProgram'].Value = $env:ComSpec; # run cmd.exe
# pass "<project dir>\Testing\Debug.cmd" as the program to run from cmd.exe
$dteProject.Properties['WebApplication.StartCmdLineArguments'].Value = "/C `"${debugScriptPath}`"";
}
# Release our COM object reference
[Runtime.InteropServices.Marshal]::ReleaseComObject($dteCOMObject) | Out-Null;
}
2) Call the PowerShell script from your project post-build like:
powershell.exe -File "$(ProjectDir)script.ps1" "$(ProjectPath)" "$(ProjectDir)Testing\Debug.cmd"
The first parameter (after -File) is the path to the script you created in step 1, the second parameter is the path to the project being built, and the third parameter (which your script will probably not have unless you're trying to do exactly what I am) is the path to the batch file/script that to be configured to run when debugging with an external program.
Workaround for users limited to running under a Restricted execution policy
(ie. powershell.exe -Command "Set-ExecutionPolicy Unrestricted" does not work)
If PowerShell is locked into the Restricted execution policy you will not be able to run a PowerShell script either using powershell.exe -File script.ps1 commands or through dot-sourcing methods like powershell.exe -Command ". .\script.ps1". However, I've discovered that you can read a script into a variable and then run Invoke-Expression $ScriptContent. (Seems odd to me that this works, but it does)
The workaround consists of:
1) Create a PowerShell script using the same content from above, but exclude the Param(...) lines at the top.
2) Call the PowerShell script from your project post-build like:
powershell -Command "& { $projPath='$(ProjectPath)'; $debugScriptPath='$(ProjectDir)Testing\Debug.cmd'; Get-Content '$(ProjectDir)script.ps1' -Encoding String | ? { $_ -match '^^\s*[^^#].*$' } | %% { $VSTweaks += $_ + """`r`n"""; }; Invoke-Expression $VSTweaks; } }"
This reads contents of script.ps1 into a variable named $VSTweaks (skipping lines that are only comments - ie. digital signature lines which cause problems in some scenarios), and then runs the script contents with Invoke-Expression. The values that were passed into $projPath and $debugScriptPath through parameters in the original script are now set at the beginning of the call in powershell.exe -Command "& { $projPath ...}. (If they are not set then the script will fail)
NOTE: Because the VS project post-build event contents are executed as a Windows batch file you have to escape a lot of characters that are special to Windows batch files. That explains some of the confusing character combinations in the script
% = %%
^ = ^^
" = """ (I'm honestly not sure why this is required, but it seems to be)
Tip
I've started wrapping the entire PowerShell call (<PowerShell commands> in the example below) in try catch statements in order to make any PowerShell errors show up in the Visual Studio "Error List..." view when a build fails.
powershell -Command "& { try { <PowerShell commands> } catch { Write-Host "post-build : PowerShell error $^($_.Exception.HResult^) : $_"; exit $_.Exception.HResult; } }"
The resulting error message in VS looks like this:
You can run a VBScript file (.vbs) with code like this:
Dim dte
Set dte = GetObject(, "VisualStudio.DTE")
dte.ExecuteCommand("Help.About")
While I was trying to find a solution I briefly looked into making my own .NET PowerShell cmdlet that would return the EnvDTE.DTE object for the instance of VS that started the PowerShell script.
The code is ugly, but it works and it met my requirements for the most part (more on that in the notes at the end). So, I thought I'd go ahead and include it as an answer as well just in case someone prefers this method or needs a starting point for making their own DTE cmdlet.
Usage Example:
PS C:\> Import-Module .\GetDTECmdlet.dll;
PS C:\> $dte = Get-DTE | Select-Object -First 1;
PS C:\> $dte = Get-DTE -ProcID 8547 | Select-Object -First 1;
PS C:\> $dte = Get-DTE -FromAncestorProcs | Select-Object -First 1;
PS C:\> $dte.ExecuteCommand('Help.About');
PS C:\> [Runtime.InteropServices.Marshal]::ReleaseComObject($dte); | Out-Null;
Cmdlet Parameters:
-ProcID <int>: int = the process ID (PID) of a running instance of Visual studio to get the DTE from
-FromAncestorProcs: If this switch is specified then the Get-DTE will limit its search of DTE objects to Visual Studio processes higher up in the process tree (ie. parent/ancestor processes) from the PowerShell session that called it.
Source Code:
(Make sure your project references System.Management.Automation.dll and envdte.dll)
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Management.Automation;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace VSAutomation
{
[Cmdlet(VerbsCommon.Get, "DTE")]
[OutputType(typeof(EnvDTE.DTE))]
public class GetDTECmdlet : Cmdlet, IDisposable
{
private Int32 procID = -1;
private IBindCtx bindCtx = null;
private IRunningObjectTable rot = null;
private IEnumMoniker monikerEnumerator = null;
private IMoniker[] moniker = new IMoniker[1];
private ProcCollection matchingProcs = new ProcCollection();
[Parameter]
public SwitchParameter FromAncestorProcs { get; set; }
[Parameter]
public Int32 ProcID { get { return procID; } set { procID = value; } }
protected override void BeginProcessing()
{
base.BeginProcessing();
Marshal.ThrowExceptionForHR(OLE32.CreateBindCtx(0, out bindCtx));
bindCtx.GetRunningObjectTable(out rot);
rot.EnumRunning(out monikerEnumerator);
}
protected override void ProcessRecord()
{
base.ProcessRecord();
Regex VSMonikerNameRegex = new Regex(#"^!?VisualStudio\.DTE([\.\d]+)?:(?<PID>\d+)$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
// Get a list of ancestor PIDs if the results should be limited based on ancestor processes
if (FromAncestorProcs.IsPresent)
{
try
{
using (Process thisProc = Process.GetCurrentProcess())
{
Process proc = thisProc;
Int32 parentProcID;
while ((parentProcID = NTDLL.GetParentProcessID(proc.Handle)) != 0)
{
proc = Process.GetProcessById(parentProcID);
matchingProcs.Add(new ROTProc(proc));
}
}
}
catch { }
}
// Loop through the running objects and find a suitable DTE
while (monikerEnumerator.Next(1, moniker, IntPtr.Zero) == 0)
{
Object runningObject;
IMoniker runningObjectMoniker = moniker[0];
if (!FromAncestorProcs.IsPresent && ProcID == -1)
{
// Returning all DTE objects from running processes
//Only return each object once
if (!matchingProcs.Contains(runningObjectMoniker))
{
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
EnvDTE.DTE dte = runningObject as EnvDTE.DTE;
if (dte != null && !matchingProcs.Contains(dte))
{
matchingProcs.Add(new ROTProc(dte, runningObjectMoniker));
WriteObject(runningObject);
}
}
continue;
}
// Returning only DTE objects from ancestor processes or a specific process
Match nameMatch;
String name = null;
try
{
if (runningObjectMoniker != null)
runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
}
catch (UnauthorizedAccessException)
{
// Do nothing, there is something in the ROT that we do not have access to.
}
if (String.IsNullOrEmpty(name))
continue;
nameMatch = VSMonikerNameRegex.Match(name);
if (!nameMatch.Success)
continue;
if (ProcID != -1)
{
if (Int32.Parse(nameMatch.Groups["PID"].Value) != ProcID)
continue;
//Found a match for the specified process ID - send it to the pipeline and quit enumerating
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
if (runningObject is EnvDTE.DTE)
{
WriteObject(runningObject);
return;
}
}
// collect DTE objects so that they can be returned in order from closest ancestor to farthest ancestor in the event that VS launched VS which launched MSBUild ...
ROTProc ancestorProc = matchingProcs.GetByProcId(Int32.Parse(nameMatch.Groups["PID"].Value));
if (ancestorProc == null)
continue;
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
ancestorProc.DTE = runningObject as EnvDTE.DTE;
}
if (!FromAncestorProcs.IsPresent)
return;
for (Int32 i = 0; i < matchingProcs.Count; i++)
if (matchingProcs[i].DTE != null) WriteObject(matchingProcs[i].DTE);
}
protected override void EndProcessing()
{
base.EndProcessing();
Dispose();
}
protected override void StopProcessing()
{
base.StopProcessing();
Dispose();
}
public void Dispose()
{
if (monikerEnumerator != null)
{
Marshal.ReleaseComObject(monikerEnumerator);
monikerEnumerator = null;
}
if (rot != null)
{
Marshal.ReleaseComObject(rot);
rot = null;
}
if (bindCtx != null)
{
Marshal.ReleaseComObject(bindCtx);
bindCtx = null;
}
if (matchingProcs != null)
{
matchingProcs.Dispose();
matchingProcs = null;
}
}
private class ROTProc : IDisposable
{
public Process Proc = null;
public EnvDTE.DTE DTE = null;
public IMoniker Moniker = null;
public IntPtr COMPtr = IntPtr.Zero;
public ROTProc(Process Proc, EnvDTE.DTE DTE = null, IMoniker Moniker = null)
{
this.Proc = Proc;
this.DTE = DTE;
this.Moniker = Moniker;
if (DTE != null)
COMPtr = Marshal.GetComInterfaceForObject(DTE, typeof(EnvDTE._DTE));
}
public ROTProc(EnvDTE.DTE DTE, IMoniker Moniker) : this(null, DTE, Moniker) { }
public void Dispose()
{
if (Proc != null)
{
try { Proc.Dispose(); }
catch (ObjectDisposedException) { }
Proc = null;
}
if (COMPtr != IntPtr.Zero)
{
try { Marshal.Release(COMPtr); }
catch { }
COMPtr = IntPtr.Zero;
}
}
}
private class ProcCollection : System.Collections.CollectionBase, IDisposable
{
public ROTProc this[Int32 index]
{
get { return InnerList[index] as ROTProc; }
set { InnerList[index] = value; }
}
public Int32 Add(ROTProc p)
{
return InnerList.Add(p);
}
public Boolean Contains(IMoniker Moniker)
{
if (Moniker == null)
return false;
foreach (ROTProc p in this)
if (p != null && Moniker.IsEqual(p.Moniker) == 0) return true;
return false;
}
public Boolean Contains(EnvDTE.DTE DTE)
{
if (DTE == null)
return false;
foreach (ROTProc p in this)
{
if (p != null && (
Marshal.Equals(DTE, p.DTE) ||
Marshal.GetComInterfaceForObject(DTE, typeof(EnvDTE._DTE)) == p.COMPtr))
{
return true;
}
}
return false;
}
public ROTProc GetByProcId(Int32 ProcId)
{
foreach (ROTProc p in this)
if (p != null && p.Proc != null && p.Proc.Id == ProcId) return p;
return null;
}
public void Dispose()
{
foreach (ROTProc p in this)
{
try { if (p != null) p.Dispose(); }
catch (ObjectDisposedException) { }
}
}
}
}
#region Supporting interop classes
public static class OLE32
{
[DllImport("ole32.dll")]
public static extern Int32 CreateBindCtx(UInt32 reserved, out IBindCtx ppbc);
}
public static class NTDLL
{
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
public IntPtr Reserved1;
public IntPtr PebBaseAddress;
public IntPtr Reserved2_0;
public IntPtr Reserved2_1;
public IntPtr UniqueProcessId;
public IntPtr ParentUniqueProcessId;
}
public static Int32 GetParentProcessID(IntPtr handle)
{
PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
Int32 returnLength;
UInt32 status = NtQueryInformationProcess(handle, IntPtr.Zero, ref pbi, Marshal.SizeOf(pbi), out returnLength);
if (status != 0)
return 0;
return pbi.ParentUniqueProcessId.ToInt32();
}
[DllImport("ntdll.dll")]
private static extern UInt32 NtQueryInformationProcess(IntPtr processHandle, IntPtr processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, Int32 processInformationLength, out Int32 returnLength);
}
#endregion Supporting interop classes
}
NOTE: I still prefer the single PowerShell script solution to this one (posted in another answer). But that's mainly because of the Restricted execution policy that is enforced in my environment. Because of that, even when I was using this cmdlet to do the heavy lifting of getting the DTE reference, the rest of my PowerShell code had to be compressed into an ugly, batch escaped, hard to understand, single line of code (ie powershell.exe -Command " ... %% ^^ ... ").
Even as I was writing it I found it hard to follow. So, I knew any future developers picking up the project would have been cursing me if they ever had to tweak it.
While trying to find a way to get around the "ugly one-liner" problem, I discovered the method of using Get-Content and Invoke-Expression to "psuedo-source" PowerShell scripts. Once I had that routine down I decided I'd rather have a single PowerShell script rather than a project to make a cmdlet and a PowerShell script using it.
Knowing the hwnd of the window, how do I read the contents of this? Before anyone ask me, I'm trying to get the text that was used in the Communicator window.
Below is the code I found on the Internet.
The code is not mine.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace EventFun
{
class EventHookUp
{
CommunicatorAPI.Messenger mCommunicator = null;
static void Main(string[] args)
{
EventHookUp hu = new EventHookUp();
hu.InitializeEventHocks();
Console.ReadKey();
}
public void InitializeEventHocks()
{
mCommunicator = new CommunicatorAPI.Messenger();
mCommunicator.OnIMWindowCreated += new CommunicatorAPI.DMessengerEvents_OnIMWindowCreatedEventHandler(mCommunicator_OnIMWindowCreated);
mCommunicator.OnIMWindowDestroyed += new CommunicatorAPI.DMessengerEvents_OnIMWindowDestroyedEventHandler(mCommunicator_OnIMWindowDestroyed);
}
void mCommunicator_OnIMWindowCreated(object pIMWindow)
{
CommunicatorAPI.IMessengerConversationWndAdvanced stpIMWindow = pIMWindow as CommunicatorAPI.IMessengerConversationWndAdvanced;
//stpIMWindow.History;
long Hwnd = (long)stpIMWindow.HWND;
Console.WriteLine("New IM Window Created : {0}", Hwnd);
CommunicatorAPI.IMessengerContacts contactList = (CommunicatorAPI.IMessengerContacts)stpIMWindow.Contacts;
StringBuilder sb = new StringBuilder();
foreach (CommunicatorAPI.IMessengerContact imc in contactList)
{
sb.Append(imc.FriendlyName);
sb.Append(Environment.NewLine);
}
Console.WriteLine(sb.ToString());
}
void mCommunicator_OnIMWindowDestroyed(object pIMWindow)
{
Console.WriteLine("IM Window Destroyed.");
}
}
}
It sounds like you are trying to get the conversation text history from the conversation window? If so, George Durzi has an excellent blog post on this.
As this blog post is not available, I used below method to retrieve the conversation history:
object obj = msgrAdv.StartConversation(
CONVERSATION_TYPE.CONVERSATION_TYPE_IM, // Type of conversation
sipUris, // object array of signin names for having multiple conversations or just a string
null,
"Test",
"1",
null);
imWindowHandle = long.Parse(obj.ToString());
if (imWindow == null) //If there is already an open window...
{
imWindow = (IMessengerConversationWndAdvanced)msgrAdv.InstantMessage(sipUris);
}
//else there was no open window, we have opened the window using "msgrAdv.StartConversation" so there is a imWindow associated which is implemented in communicator_OnIMWindowCreated.
//and then...
string history = imWindow.History;
I'm new to Windows Forms, in my project, i need to change the image in the picture box at runtime. I'm able to do that with the help of a timer. The picture just gets changed. Is it possible to do some transitions when image changes, for example fade in, fade out, blur etc.. If possible could some one please let me know how to do it. I searched in net but in vain.Thanks in advance.
Varun
Simply take new code file and paste below code in it
an original answer for the similar question, answer taken from another question
Answer
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class BlendPanel : Panel
{
private Image mImg1;
private Image mImg2;
private float mBlend;
public BlendPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
public Image Image1
{
get { return mImg1; }
set { mImg1 = value; Invalidate(); }
}
public Image Image2
{
get { return mImg2; }
set { mImg2 = value; Invalidate(); }
}
public float Blend
{
get { return mBlend; }
set { mBlend = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if (mImg1 == null || mImg2 == null)
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
else
{
Rectangle rc = new Rectangle(0, 0, this.Width, this.Height);
ColorMatrix cm = new ColorMatrix();
ImageAttributes ia = new ImageAttributes();
cm.Matrix33 = mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia);
cm.Matrix33 = 1F - mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia);
}
base.OnPaint(e);
}
}
Build your project. You can now drop a BlendPanel from the top of the toolbox onto your form. Here's a sample program that uses it:
private float mBlend;
private int mDir = 1;
public int count = 0;
public Bitmap[] pictures;
public void myPhoto()
{
pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
timer1.Interval = 50; //time of transition
timer1.Tick += BlendTick;
try
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
catch
{
}
timer1.Enabled = true;
}
private void BlendTick(object sender, EventArgs e)
{
mBlend += mDir * 0.02F;
if (mBlend > 1)
{
mBlend = 0.0F;
if ((count + 1) < pictures.Length)
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
else
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[0];
count = 0;
}
}
blendPanel1.Blend = mBlend;
}
You'll need to modify the new Bitmap(#"yourimagePath"); calls. Build and run. You should see the displayed image smoothly morph from your first image to your second image without any flickering.
I hope it helps for other...
There is no built-in support for such effects, but you can implement them. I'd suggest to write a custom control that renders the image and have a method for fade-swap, fade itself can be reached with alpha-blending drawing with .NET Graphics class.
However, Graphics class isn't very fast, I don't recommend to use this technique for big images. If you need some fancy UI with hw-accelerated effects, take a look at WPF.
Blend effects are easy to get going by using the ColorMatrix class. There's a good example available in my answer in this thread.
A simple way to get a blur is to resize the image, making it smaller, then redraw it back, making it larger. The Graphics.InterpolationMode property affects the type of blur you'll get.
Those are quicky do-it-yourself solutions. Any decent graphics library has these kind of operations built-in. You probably want something free, check out ImageMagick.NET
To put it simply, not without external (3rd-party) libraries.