2872f147f8
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request Every single time a PR is run, there are a bunch of warnings about whitespace in the .cs files, so I ran the code format on those files, without changing their contents, so it won't be flagged anymore. <!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> ## References <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist * [X] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [X] Tests added/passed <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed Ran the code-format utility on the .cs files
179 lines
6.5 KiB
C#
179 lines
6.5 KiB
C#
//----------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="ShortcutHelper.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
// <summary>Console UI Automation shortcut file manipulation</summary>
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
namespace Conhost.UIA.Tests.Common
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using WEX.Common.Managed;
|
|
using WEX.Logging.Interop;
|
|
using WEX.TestExecution;
|
|
using WEX.TestExecution.Markup;
|
|
|
|
using Conhost.UIA.Tests.Common.NativeMethods;
|
|
|
|
public class ShortcutHelper : IDisposable
|
|
{
|
|
private bool isDisposed = false;
|
|
|
|
public string ShortcutPath { get; private set; }
|
|
|
|
public ShortcutHelper()
|
|
{
|
|
this.ShortcutPath = null;
|
|
}
|
|
|
|
~ShortcutHelper()
|
|
{
|
|
this.Dispose(false);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
this.Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (!this.isDisposed)
|
|
{
|
|
this.CleanupTempCmdShortcut();
|
|
}
|
|
|
|
this.isDisposed = true;
|
|
}
|
|
|
|
public void CreateTempCmdShortcut()
|
|
{
|
|
string tempPath = Path.Combine(Path.GetTempPath(), AutoHelpers.FormatInvariant("{0}.lnk", Path.GetRandomFileName()));
|
|
AutoHelpers.LogInvariant("Creating temporary shortcut: {0}", tempPath);
|
|
|
|
Shell32.IShellLinkW link = (Shell32.IShellLinkW)new Shell32.ShellLink();
|
|
link.SetDescription("Created by Conhost.UIA.Tests.Common.ShortcutHelper");
|
|
link.SetPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "cmd.exe"));
|
|
|
|
Shell32.IPersistFile persist = (Shell32.IPersistFile)link; // performs QI
|
|
persist.Save(tempPath, false);
|
|
|
|
this.ShortcutPath = tempPath;
|
|
}
|
|
|
|
public void CleanupTempCmdShortcut()
|
|
{
|
|
if (!string.IsNullOrEmpty(this.ShortcutPath))
|
|
{
|
|
File.Delete(this.ShortcutPath);
|
|
this.ShortcutPath = null;
|
|
}
|
|
}
|
|
|
|
public WinConP.NT_CONSOLE_PROPS GetConsoleProps()
|
|
{
|
|
Shell32.IPersistFile persist = (Shell32.IPersistFile)new Shell32.ShellLink();
|
|
persist.Load(this.ShortcutPath, (uint)ObjBase.STGM.STGM_READ);
|
|
|
|
Shell32.IShellLinkDataList sldl = (Shell32.IShellLinkDataList)persist;
|
|
|
|
WinConP.NT_CONSOLE_PROPS props = new WinConP.NT_CONSOLE_PROPS();
|
|
IntPtr ppDataBlock = Marshal.AllocHGlobal(Marshal.SizeOf(props));
|
|
|
|
try
|
|
{
|
|
sldl.CopyDataBlock(WinConP.NT_CONSOLE_PROPS_SIG, out ppDataBlock);
|
|
|
|
// The marshaler doesn't like using the existing instance that we made above because it's a value type and
|
|
// there are potential string pointers here. Give it the type instead and it can handle setting everything up.
|
|
props = (WinConP.NT_CONSOLE_PROPS)Marshal.PtrToStructure(ppDataBlock, typeof(WinConP.NT_CONSOLE_PROPS));
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(ppDataBlock);
|
|
}
|
|
|
|
return props;
|
|
}
|
|
|
|
public void SetConsoleProps(WinConP.NT_CONSOLE_PROPS props)
|
|
{
|
|
Shell32.IPersistFile persist = (Shell32.IPersistFile)new Shell32.ShellLink();
|
|
persist.Load(this.ShortcutPath, (uint)ObjBase.STGM.STGM_READWRITE);
|
|
|
|
Shell32.IShellLinkDataList sldl = (Shell32.IShellLinkDataList)persist;
|
|
|
|
sldl.RemoveDataBlock(WinConP.NT_CONSOLE_PROPS_SIG);
|
|
|
|
IntPtr ppDataBlock = Marshal.AllocHGlobal(Marshal.SizeOf(props));
|
|
try
|
|
{
|
|
Marshal.StructureToPtr(props, ppDataBlock, false);
|
|
|
|
// we are assuming that the signature is set properly on the NT_CONSOLE_PROPS structure
|
|
Verify.AreEqual(props.dbh.dwSignature, (int)WinConP.NT_CONSOLE_PROPS_SIG);
|
|
sldl.AddDataBlock(ppDataBlock);
|
|
|
|
persist.Save(null, true); // 2nd var is ignored when 1st is null
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(ppDataBlock);
|
|
}
|
|
}
|
|
|
|
public IDictionary<Wtypes.PROPERTYKEY, object> GetFromPropertyStore(IEnumerable<Wtypes.PROPERTYKEY> keys)
|
|
{
|
|
if (keys == null)
|
|
{
|
|
throw new NotSupportedException(AutoHelpers.FormatInvariant("Keys passed cannot be null"));
|
|
}
|
|
|
|
Shell32.IPersistFile persist = (Shell32.IPersistFile)new Shell32.ShellLink();
|
|
persist.Load(this.ShortcutPath, (uint)ObjBase.STGM.STGM_READ);
|
|
|
|
Shell32.IPropertyStore store = (Shell32.IPropertyStore)persist;
|
|
|
|
Dictionary<Wtypes.PROPERTYKEY, object> results = new Dictionary<Wtypes.PROPERTYKEY, object>();
|
|
|
|
foreach (Wtypes.PROPERTYKEY key in keys)
|
|
{
|
|
Wtypes.PROPERTYKEY pkey = key; // iteration variables are read-only and we need to pass by ref
|
|
object pv;
|
|
store.GetValue(ref pkey, out pv);
|
|
|
|
results.Add(key, pv);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
public void SetToPropertyStore(IDictionary<Wtypes.PROPERTYKEY, object> properties)
|
|
{
|
|
if (properties == null)
|
|
{
|
|
throw new NotSupportedException(AutoHelpers.FormatInvariant("Properties passed cannot be null."));
|
|
}
|
|
|
|
Shell32.IPersistFile persist = (Shell32.IPersistFile)new Shell32.ShellLink();
|
|
persist.Load(this.ShortcutPath, (uint)ObjBase.STGM.STGM_READWRITE);
|
|
|
|
Shell32.IPropertyStore store = (Shell32.IPropertyStore)persist;
|
|
|
|
foreach (Wtypes.PROPERTYKEY key in properties.Keys)
|
|
{
|
|
Wtypes.PROPERTYKEY pkey = key; // iteration variables are read-only and we need to pass by ref
|
|
object pv = properties[key];
|
|
|
|
store.SetValue(ref pkey, ref pv);
|
|
}
|
|
|
|
persist.Save(null, true);
|
|
}
|
|
}
|
|
}
|