Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- $ErrorActionPreference = "Stop"
- # Confirm Administrator rights.
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = New-Object Security.Principal.WindowsPrincipal($identity)
- if (-not $principal.IsInRole(
- [Security.Principal.WindowsBuiltInRole]::Administrator
- )) {
- Write-Host ""
- Write-Host "Open Windows PowerShell as Administrator, then paste this again." `
- -ForegroundColor Red
- return
- }
- Add-Type -AssemblyName System.Drawing
- Add-Type -AssemblyName System.Windows.Forms
- $DeployRoot = "C:\Deploy\TrayTime"
- $LogDir = Join-Path $DeployRoot "log"
- $InstallDir = "C:\ProgramData\TrayTime"
- $SourceFile = Join-Path $DeployRoot "TrayTime.cs"
- $DeployIcon = Join-Path $DeployRoot "TrayTime.ico"
- $DeployExe = Join-Path $DeployRoot "TrayTime.exe"
- $InstalledExe = Join-Path $InstallDir "TrayTime.exe"
- $InstalledIcon = Join-Path $InstallDir "TrayTime.ico"
- $UninstallScript = Join-Path $DeployRoot "Uninstall-TrayTime.ps1"
- $StartMenuFolder = Join-Path `
- $env:ProgramData `
- "Microsoft\Windows\Start Menu\Programs\TrayTime"
- $Stamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
- $LogFile = Join-Path $LogDir "TrayTime_Install_$Stamp.log"
- New-Item -ItemType Directory -Path $DeployRoot -Force | Out-Null
- New-Item -ItemType Directory -Path $LogDir -Force | Out-Null
- New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
- New-Item -ItemType Directory -Path $StartMenuFolder -Force | Out-Null
- Start-Transcript -Path $LogFile -Force
- try {
- Write-Host ""
- Write-Host "Installing TrayTime..." -ForegroundColor Cyan
- Write-Host "Started: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
- Write-Host "Computer: $env:COMPUTERNAME"
- # Stop an older running version before replacing it.
- Get-Process TrayTime -ErrorAction SilentlyContinue |
- Stop-Process -Force -ErrorAction SilentlyContinue
- # Remove older per-user shortcuts and startup entries.
- Remove-ItemProperty `
- -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" `
- -Name "TrayTime" `
- -ErrorAction SilentlyContinue
- $OldUserStartMenu = Join-Path `
- ([Environment]::GetFolderPath("Programs")) `
- "TrayTime"
- Remove-Item `
- -LiteralPath $OldUserStartMenu `
- -Recurse `
- -Force `
- -ErrorAction SilentlyContinue
- $OldDesktopShortcut = Join-Path `
- ([Environment]::GetFolderPath("Desktop")) `
- "TrayTime.lnk"
- Remove-Item `
- -LiteralPath $OldDesktopShortcut `
- -Force `
- -ErrorAction SilentlyContinue
- # ------------------------------------------------------------
- # Create the dark-green circular icon with bold white T.
- # ------------------------------------------------------------
- $bitmap = New-Object System.Drawing.Bitmap 64,64
- $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
- $graphics.SmoothingMode = `
- [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
- $graphics.TextRenderingHint = `
- [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
- $graphics.Clear([System.Drawing.Color]::Transparent)
- $circleBrush = New-Object System.Drawing.SolidBrush(
- [System.Drawing.Color]::FromArgb(255, 0, 85, 35)
- )
- $letterBrush = New-Object System.Drawing.SolidBrush(
- [System.Drawing.Color]::White
- )
- $font = New-Object System.Drawing.Font(
- "Arial",
- 40,
- [System.Drawing.FontStyle]::Bold,
- [System.Drawing.GraphicsUnit]::Pixel
- )
- $format = New-Object System.Drawing.StringFormat
- $format.Alignment = [System.Drawing.StringAlignment]::Center
- $format.LineAlignment = [System.Drawing.StringAlignment]::Center
- $graphics.FillEllipse(
- $circleBrush,
- 2,
- 2,
- 60,
- 60
- )
- $graphics.DrawString(
- "T",
- $font,
- $letterBrush,
- (New-Object System.Drawing.RectangleF 0,0,64,61),
- $format
- )
- $iconHandle = $bitmap.GetHicon()
- $icon = [System.Drawing.Icon]::FromHandle($iconHandle)
- $iconStream = [System.IO.File]::Create($DeployIcon)
- $icon.Save($iconStream)
- $iconStream.Close()
- $graphics.Dispose()
- $bitmap.Dispose()
- $circleBrush.Dispose()
- $letterBrush.Dispose()
- $font.Dispose()
- $format.Dispose()
- Write-Host "Created icon: $DeployIcon"
- # ------------------------------------------------------------
- # TrayTime application source.
- # ------------------------------------------------------------
- $csharp = @'
- using System;
- using System.Drawing;
- using System.IO;
- using System.Threading;
- using System.Windows.Forms;
- public static class TrayTimeProgram
- {
- private static NotifyIcon tray;
- private static ContextMenuStrip menu;
- private static ToolStripMenuItem[] dateItems;
- private static Mutex mutex;
- [STAThread]
- public static void Main()
- {
- bool createdNew;
- mutex = new Mutex(
- true,
- @"Global\TrayTime_SingleInstance",
- out createdNew
- );
- if (!createdNew)
- {
- return;
- }
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- menu = new ContextMenuStrip();
- dateItems = new ToolStripMenuItem[4];
- for (int i = 0; i < 4; i++)
- {
- ToolStripMenuItem item = new ToolStripMenuItem();
- item.Click += delegate(object sender, EventArgs args)
- {
- ToolStripMenuItem clicked =
- (ToolStripMenuItem)sender;
- string value =
- Convert.ToString(clicked.Tag);
- if (!String.IsNullOrEmpty(value))
- {
- Clipboard.SetText(value);
- tray.BalloonTipTitle =
- "Copied to clipboard";
- tray.BalloonTipText = value;
- tray.ShowBalloonTip(900);
- }
- };
- dateItems[i] = item;
- menu.Items.Add(item);
- }
- menu.Items.Add(new ToolStripSeparator());
- ToolStripMenuItem exitItem =
- new ToolStripMenuItem("Exit TrayTime");
- exitItem.Click += delegate
- {
- tray.Visible = false;
- Application.Exit();
- };
- menu.Items.Add(exitItem);
- menu.Opening += delegate
- {
- UpdateMenu();
- };
- tray = new NotifyIcon();
- string iconPath = Path.Combine(
- AppDomain.CurrentDomain.BaseDirectory,
- "TrayTime.ico"
- );
- if (File.Exists(iconPath))
- {
- tray.Icon = new Icon(iconPath);
- }
- else
- {
- tray.Icon = SystemIcons.Information;
- }
- tray.Text =
- "TrayTime - click a date to copy";
- tray.ContextMenuStrip = menu;
- tray.Visible = true;
- // Left-click opens the same menu.
- // Right-click works through ContextMenuStrip.
- tray.MouseClick += delegate(
- object sender,
- MouseEventArgs args
- )
- {
- if (args.Button == MouseButtons.Left)
- {
- UpdateMenu();
- menu.Show(Cursor.Position);
- }
- };
- // Double-click copies the longest format.
- tray.DoubleClick += delegate
- {
- string value = GetDateStrings()[3];
- Clipboard.SetText(value);
- tray.BalloonTipTitle =
- "Copied to clipboard";
- tray.BalloonTipText = value;
- tray.ShowBalloonTip(900);
- };
- try
- {
- Application.Run();
- }
- finally
- {
- tray.Visible = false;
- tray.Dispose();
- menu.Dispose();
- try
- {
- mutex.ReleaseMutex();
- }
- catch
- {
- }
- mutex.Dispose();
- }
- }
- private static string[] GetDateStrings()
- {
- DateTime d = DateTime.Now;
- string[] days =
- {
- "SUN",
- "MON",
- "TUE",
- "WED",
- "THUR",
- "FRI",
- "SAT"
- };
- string[] months =
- {
- "JAN",
- "FEB",
- "MAR",
- "APR",
- "MAY",
- "JUN",
- "JUL",
- "AUG",
- "SEP",
- "OCT",
- "NOV",
- "DEC"
- };
- string dow = days[(int)d.DayOfWeek];
- string month = months[d.Month - 1];
- string date = String.Format(
- "{0}-{1}-{2}",
- d.Day,
- month,
- d.Year
- );
- return new string[]
- {
- date,
- String.Format(
- "{0}, {1}",
- dow,
- date
- ),
- String.Format(
- "Day {0} - {1}, {2}",
- d.DayOfYear,
- dow,
- date
- ),
- String.Format(
- "Day {0}: {1}, {2}",
- d.DayOfYear,
- dow,
- date
- )
- };
- }
- private static void UpdateMenu()
- {
- string[] values = GetDateStrings();
- for (int i = 0; i < dateItems.Length; i++)
- {
- dateItems[i].Text = values[i];
- dateItems[i].Tag = values[i];
- }
- }
- }
- '@
- [System.IO.File]::WriteAllText(
- $SourceFile,
- $csharp,
- [System.Text.UTF8Encoding]::new($true)
- )
- Remove-Item `
- -LiteralPath $DeployExe `
- -Force `
- -ErrorAction SilentlyContinue
- Write-Host "Compiling TrayTime.exe..."
- Add-Type `
- -TypeDefinition $csharp `
- -Language CSharp `
- -ReferencedAssemblies @(
- "System.dll",
- "System.Drawing.dll",
- "System.Windows.Forms.dll"
- ) `
- -OutputAssembly $DeployExe `
- -OutputType WindowsApplication
- if (-not (Test-Path $DeployExe)) {
- throw "TrayTime.exe was not created."
- }
- Copy-Item $DeployExe $InstalledExe -Force
- Copy-Item $DeployIcon $InstalledIcon -Force
- Write-Host "Installed application: $InstalledExe"
- # ------------------------------------------------------------
- # Start TrayTime for every user at sign-in.
- # ------------------------------------------------------------
- $MachineRunKey = `
- "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
- New-Item -Path $MachineRunKey -Force | Out-Null
- New-ItemProperty `
- -Path $MachineRunKey `
- -Name "TrayTime" `
- -Value "`"$InstalledExe`"" `
- -PropertyType String `
- -Force | Out-Null
- Write-Host "Added all-users startup entry."
- # ------------------------------------------------------------
- # Create uninstaller.
- # ------------------------------------------------------------
- $uninstallSource = @'
- $ErrorActionPreference = "SilentlyContinue"
- $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
- $principal = New-Object Security.Principal.WindowsPrincipal($identity)
- $isAdmin = $principal.IsInRole(
- [Security.Principal.WindowsBuiltInRole]::Administrator
- )
- if (-not $isAdmin) {
- Start-Process powershell.exe `
- -Verb RunAs `
- -ArgumentList @(
- "-NoProfile",
- "-ExecutionPolicy",
- "Bypass",
- "-File",
- "`"$PSCommandPath`""
- )
- exit
- }
- Add-Type -AssemblyName System.Windows.Forms
- Get-Process TrayTime -ErrorAction SilentlyContinue |
- Stop-Process -Force -ErrorAction SilentlyContinue
- Remove-ItemProperty `
- -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" `
- -Name "TrayTime" `
- -ErrorAction SilentlyContinue
- $StartMenuFolder = Join-Path `
- $env:ProgramData `
- "Microsoft\Windows\Start Menu\Programs\TrayTime"
- $InstallDir = "C:\ProgramData\TrayTime"
- Remove-Item `
- -LiteralPath $StartMenuFolder `
- -Recurse `
- -Force `
- -ErrorAction SilentlyContinue
- Remove-Item `
- -LiteralPath $InstallDir `
- -Recurse `
- -Force `
- -ErrorAction SilentlyContinue
- [System.Windows.Forms.MessageBox]::Show(
- "TrayTime was uninstalled.",
- "TrayTime",
- [System.Windows.Forms.MessageBoxButtons]::OK,
- [System.Windows.Forms.MessageBoxIcon]::Information
- ) | Out-Null
- '@
- [System.IO.File]::WriteAllText(
- $UninstallScript,
- $uninstallSource,
- [System.Text.UTF8Encoding]::new($true)
- )
- # ------------------------------------------------------------
- # Create Start Menu shortcuts for all users.
- # ------------------------------------------------------------
- Remove-Item `
- -LiteralPath $StartMenuFolder `
- -Recurse `
- -Force `
- -ErrorAction SilentlyContinue
- New-Item `
- -ItemType Directory `
- -Path $StartMenuFolder `
- -Force | Out-Null
- $shell = New-Object -ComObject WScript.Shell
- $OpenShortcut = Join-Path `
- $StartMenuFolder `
- "Open TrayTime.lnk"
- $open = $shell.CreateShortcut($OpenShortcut)
- $open.TargetPath = $InstalledExe
- $open.WorkingDirectory = $InstallDir
- $open.IconLocation = $InstalledIcon
- $open.Description = "Open TrayTime"
- $open.Save()
- $UninstallShortcut = Join-Path `
- $StartMenuFolder `
- "Uninstall TrayTime.lnk"
- $remove = $shell.CreateShortcut($UninstallShortcut)
- $remove.TargetPath = "powershell.exe"
- $remove.Arguments = (
- '-NoProfile -ExecutionPolicy Bypass -File "{0}"' `
- -f $UninstallScript
- )
- $remove.WorkingDirectory = $DeployRoot
- $remove.IconLocation = $InstalledIcon
- $remove.Description = "Uninstall TrayTime"
- $remove.Save()
- Write-Host "Created all-users Start Menu folder:"
- Write-Host $StartMenuFolder
- # Ensure there is no desktop shortcut.
- $DesktopFolders = @(
- [Environment]::GetFolderPath("Desktop"),
- "$env:PUBLIC\Desktop"
- )
- foreach ($DesktopFolder in $DesktopFolders) {
- if ($DesktopFolder) {
- Remove-Item `
- -LiteralPath (
- Join-Path $DesktopFolder "TrayTime.lnk"
- ) `
- -Force `
- -ErrorAction SilentlyContinue
- }
- }
- # Start TrayTime now.
- Start-Process `
- -FilePath $InstalledExe `
- -WorkingDirectory $InstallDir
- Start-Sleep -Seconds 2
- $process = Get-Process TrayTime -ErrorAction SilentlyContinue
- if (-not $process) {
- throw "TrayTime installed, but its process did not start."
- }
- $hash = Get-FileHash `
- -LiteralPath $InstalledExe `
- -Algorithm SHA256
- Write-Host ""
- Write-Host "TrayTime installed successfully." `
- -ForegroundColor Green
- Write-Host "Application: $InstalledExe"
- Write-Host "Start Menu: TrayTime"
- Write-Host "Log: $LogFile"
- Write-Host "SHA256: $($hash.Hash)"
- # Restart Explorer so the new Start Menu folder appears immediately.
- Write-Host "Refreshing Windows Explorer..."
- Get-Process explorer -ErrorAction SilentlyContinue |
- Stop-Process -Force -ErrorAction SilentlyContinue
- Start-Sleep -Seconds 1
- Start-Process explorer.exe
- [System.Windows.Forms.MessageBox]::Show(
- "TrayTime installed successfully.`n`nStart Menu:`nTrayTime\Open TrayTime`nTrayTime\Uninstall TrayTime",
- "TrayTime Installed",
- [System.Windows.Forms.MessageBoxButtons]::OK,
- [System.Windows.Forms.MessageBoxIcon]::Information
- ) | Out-Null
- }
- catch {
- Write-Host ""
- Write-Host "TrayTime installation failed:" `
- -ForegroundColor Red
- Write-Host $_.Exception.Message `
- -ForegroundColor Red
- Write-Host "Log: $LogFile"
- [System.Windows.Forms.MessageBox]::Show(
- "TrayTime installation failed.`n`n$($_.Exception.Message)`n`nLog:`n$LogFile",
- "TrayTime Installation Failed",
- [System.Windows.Forms.MessageBoxButtons]::OK,
- [System.Windows.Forms.MessageBoxIcon]::Error
- ) | Out-Null
- }
- finally {
- Stop-Transcript
- }
Add Comment
Please, Sign In to add comment