Tuesday, December 2, 2014

Win32IProgressDialog via powershell

I had to mock progress dialog via powershell, In order for the user to get the same look and fell as according to it's windows version and theme I wanted to use the embedded Win32IProgressDialog.
The attached code contain a minimal implementation in powershell.

The output is Win32IProgressDialog that inherit the user theme containing animation in both the dialog and the system tray.



minimal unmanaged type declaration:
Add-Type @'
using System;
using System.Runtime.InteropServices;
using System.Text;
public class ProgressDialogg{
Win32IProgressDialog pd = null;
public void ShowDialog(string t, string c, string l1, string l2, string l3){
pd = (Win32IProgressDialog)new Win32ProgressDialog();
pd.SetTitle(t);
pd.SetCancelMsg(c, null);
pd.SetLine(1, l1, false, IntPtr.Zero);
pd.SetLine(2, l2, false, IntPtr.Zero);
pd.SetLine(3, l3, false, IntPtr.Zero);
pd.StartProgressDialog(IntPtr.Zero, null, PROGDLG.Modal, IntPtr.Zero);
}
public void SetValue(int val)
{
pd.SetProgress((uint)val, 100);
}
public static class shlwapi{
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
static extern bool PathCompactPath(IntPtr hDC, [In, Out] StringBuilder pszPath, int dx);}
[ComImport]
[Guid("EBBC7C04-315E-11d2-B62F-006097DF5BD4")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface Win32IProgressDialog{
void StartProgressDialog(IntPtr hwndParent, [MarshalAs(UnmanagedType.IUnknown)]    object punkEnableModless, PROGDLG dwFlags, IntPtr pvResevered );
void StopProgressDialog();
void SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pwzTitle );
void SetAnimation(IntPtr hInstAnimation, ushort idAnimation );
[PreserveSig]
[return: MarshalAs(UnmanagedType.Bool)]
bool HasUserCancelled();
void SetProgress(uint dwCompleted, uint dwTotal );
void SetProgress64(ulong ullCompleted, ulong ullTotal );
void SetLine(uint dwLineNum, [MarshalAs(UnmanagedType.LPWStr)] string pwzString, [MarshalAs(UnmanagedType.VariantBool)] bool fCompactPath, IntPtr pvResevered );
void SetCancelMsg([MarshalAs(UnmanagedType.LPWStr)] string pwzCancelMsg, object pvResevered );
void Timer( PDTIMER dwTimerAction, object pvResevered );}
[ComImport]
[Guid("F8383852-FCD3-11d1-A6B9-006097DF5BD4")]
public class Win32ProgressDialog{}  
public enum PDTIMER : uint {Reset = (0x01), Pause = (0x02), Resume = (0x03)}
[Flags]
public enum PROGDLG : uint
{Normal = 0x00000000, Modal = 0x00000001, AutoTime = 0x00000002, NoTime = 0x00000004, NoMinimize = 0x00000008, NoProgressBar = 0x00000010}
}
'@


Usage:
$pd = New-Object ProgressDialogg
$pd.ShowDialog("title","cancel","line1","line2","line3")
$pd.SetValue(50)

P.S
The final version with type compression
$data = [System.Convert]::FromBase64String("H4sIAAAAAAAEAJVV2W7iMBR9r9R/uOpTIgUUoOtU88BSOkilRYVOpUF9cBMXPOPYkRfoov77XCchBEo7Gnhx7ubje8+xrWZiBuMXbWhyvr9nK5/1WysMS2h9IAxVMh1TtWAR1dthE/ps0JbaR84iiDjRGkZKzhTVuscIl7PZ2/7ePROt5mDTDmkM30FYztf5C8liGM/lMg/xtFFuLxNAsYrKFW+sl831suXjdlllb9emvqBLyBybds93IOL6mJoJM5x6Zm3oEhFRPtQzD3d3eNeuKyaoh0AcmCfCNQ0A+zUyqv4Lm7YVhygd0n/GtTCu9VWcIcpswa9E5RgDGN3eXPauLutDGRP+oc77Vs+p+Um4pR4TBhaE+/t7bytQq608z6LXX7hqjTDcrKINMSUB9JwvScqwwrTH+SBJpTLeQWGtx5wfBNCdE4XFcVDFqt62RvoP+3tFKSQWVQIepeQwImbelUlKIuOWxXFh3usGMB2IAG6seYBxxoGOZTymClL96mIDcEeKn/1zBDvFIjkc3Gd6aVnsHVx0Ot2TbnhYazWOLmqNRtysdY6b/VoYHodnJ73+Uad3eOBwTTMpPJGITl5S6rlSVUO9/BrowZ34I+RSuLSiQWzlhV28xFblc/h0tjBfinhEFBWohumQKD0nvK29O5EQQWY0zjGUGwP+5ONvGhlIrfhzIcgjp8gFjoVLckC87HMy0yt6QLq4pZouqKIxuAEXoGS6Qy4r4uSC+RTS1egeB4OACommy9csA6o12oIlOHUpytMOhF5bA7B6jlMDFpe2LH86QlB4NdExm7kRKWqsEt/gMzAdZJMbSsaqH0TfYXKub07jjVOVrLcZf5aOfpwaGiOW3DKRhnDYlXN86Fku8awoxGreyvYxMxN+Udetr23yxZR3tDTn/hc5P4liRJi8AbmqniqS+gcDqrfg/8Aqs4KSjLvqT/ClUR6MepPB8OLW9dYZ2lE++52Zn6i5f9rC/1Gz1u/2Wk7NjVr7uHP2Uc0bL9aOF+Ht3SmojKPCJiW+bzkF3hwed4N54XPY8FFVxGpafDfxG/02WRlavoOcye1hq2whxqIsXr3XUiXIkO+AecUvgOwir9rw0XF3putV1YxvzPUH46EzDhmKh71uOE6dY3X0DlEVXyN8RzDvfwFpnGB7JggAAA==")
$ms = New-Object System.IO.MemoryStream
$ms.Write($data, 0, $data.Length)
$ms.Seek(0,0) | Out-Null
$sr = New-Object System.IO.StreamReader(New-Object System.IO.Compression.GZipStream($ms, [System.IO.Compression.CompressionMode]::Decompress))
Add-Type $sr.readtoend()
$pd = New-Object ProgressDialogg
$pd.ShowDialog("title","cancel","line1","line2","line3")

$pd.SetValue(50)

No comments:

Post a Comment