init
This commit is contained in:
@@ -0,0 +1,399 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Interactivity;
|
||||
using DTS.Common.Enums;
|
||||
using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
|
||||
using Microsoft.Practices.Prism.Regions;
|
||||
using DTS.Common.Events;
|
||||
|
||||
namespace DTS.Common.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Shows a popup window in response to an <see cref="Microsoft.Practices.Prism.Interactivity.InteractionRequest"/> being raised.
|
||||
/// </summary>
|
||||
public class PopupWindowAction : TriggerAction<FrameworkElement>
|
||||
{
|
||||
private Window _openedNotificationWindow;
|
||||
|
||||
#region DependecyProperties
|
||||
|
||||
public enum WindowPositions
|
||||
{
|
||||
CenterOwner,
|
||||
CenterScreen
|
||||
}
|
||||
|
||||
//public enum ResultEnum
|
||||
//{
|
||||
// Ok = MessageBoxResult.OK,
|
||||
// Yes = MessageBoxResult.Yes,
|
||||
// No = MessageBoxResult.No,
|
||||
// Cancel = MessageBoxResult.Cancel
|
||||
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// The content of the child window to display as part of the popup.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty WindowContentProperty =
|
||||
DependencyProperty.Register("WindowContent", typeof(FrameworkElement), typeof(PopupWindowAction), new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="DataTemplate"/> to apply to the popup content.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty ContentTemplateProperty =
|
||||
DependencyProperty.Register("ContentTemplate", typeof(DataTemplate), typeof(PopupWindowAction), new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the content should be shown in a modal window or not.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsModalProperty =
|
||||
DependencyProperty.Register("IsModal", typeof(bool), typeof(PopupWindowAction), new PropertyMetadata(null));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the window is shown centered over associated object or entire screen.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty StartupPositionProperty =
|
||||
DependencyProperty.Register("StartupPosition", typeof(WindowPositions), typeof(PopupWindowAction), new PropertyMetadata(WindowPositions.CenterScreen));
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the content should be initially shown centered over the View that raised the interaction request or not.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty CenterOverAssociatedObjectProperty =
|
||||
DependencyProperty.Register("CenterOverAssociatedObject", typeof(bool), typeof(PopupWindowAction), new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the multiple Notification Windows should be allowed.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty AllowMultipleNotificationWindowsProperty =
|
||||
DependencyProperty.Register("AllowMultipleNotificationWindows", typeof(bool), typeof(PopupWindowAction), new PropertyMetadata(null));
|
||||
|
||||
///// <summary>
|
||||
///// Determines timeout interval in milliseconds (0 = no timeout).
|
||||
///// </summary>
|
||||
//public static readonly DependencyProperty TimeoutIntervalProperty =
|
||||
// DependencyProperty.Register("AutoCancelInterval", typeof(int), typeof(PopupWindowAction), new PropertyMetadata(0));
|
||||
|
||||
///// <summary>
|
||||
///// Determines result if timeout occurs.
|
||||
///// </summary>
|
||||
//public static readonly ResultEnum TimeoutResultProperty =
|
||||
// DependencyProperty.Register("TimeoutResult", typeof(ResultEnum), typeof(PopupWindowAction), new PropertyMetadata(ResultEnum.Cancel));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Getters and Setters
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the window.
|
||||
/// </summary>
|
||||
public FrameworkElement WindowContent
|
||||
{
|
||||
get => (FrameworkElement)GetValue(WindowContentProperty);
|
||||
set => SetValue(WindowContentProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content template for the window.
|
||||
/// </summary>
|
||||
public DataTemplate ContentTemplate
|
||||
{
|
||||
get => (DataTemplate)GetValue(ContentTemplateProperty);
|
||||
set => SetValue(ContentTemplateProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the window will be modal or not.
|
||||
/// </summary>
|
||||
public bool IsModal
|
||||
{
|
||||
get => (bool)GetValue(IsModalProperty);
|
||||
set => SetValue(IsModalProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value whether the window is shown centered over associated object, the screen or WindowsDefault.
|
||||
/// </summary>
|
||||
public WindowPositions StartupPosition
|
||||
{
|
||||
get => (WindowPositions)GetValue(StartupPositionProperty);
|
||||
set => SetValue(StartupPositionProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value whether the multiple Notification Windows should be allowed.
|
||||
/// This property can be used for the popup window of type <see cref="NotificationWindow"/> only.
|
||||
/// </summary>
|
||||
public bool AllowMultipleNotificationWindows
|
||||
{
|
||||
get => (bool)GetValue(AllowMultipleNotificationWindowsProperty);
|
||||
set => SetValue(AllowMultipleNotificationWindowsProperty, value);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Gets or sets a value indicating number of milliseconds before dialog times out (0 = no timeout).
|
||||
///// </summary>
|
||||
//public int TimeoutInterval
|
||||
//{
|
||||
// get { return (int)GetValue(TimeoutIntervalProperty); }
|
||||
// set { SetValue(TimeoutIntervalProperty, value); }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Gets or sets a value indicating number of milliseconds before dialog times out (0 = no timeout).
|
||||
///// </summary>
|
||||
//public ResultEnum TimeoutResult
|
||||
//{
|
||||
// get { return (ResultEnum)GetValue(TimeoutResultProperty); }
|
||||
// set { SetValue(TimeoutResultProperty, value); }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PopupWindowAction logic
|
||||
|
||||
/// <summary>
|
||||
/// Displays the child window and collects results for <see cref="IInteractionRequest"/>.
|
||||
/// </summary>
|
||||
/// <param name="parameter">The parameter to the action. If the action does not require a parameter, the parameter may be set to a null reference.</param>
|
||||
protected override void Invoke(object parameter)
|
||||
{
|
||||
|
||||
var args = parameter as InteractionRequestedEventArgs;
|
||||
|
||||
if (args == null)
|
||||
return;
|
||||
|
||||
// If the WindowContent shouldn't be part of another visual tree.
|
||||
if (WindowContent != null && WindowContent.Parent != null)
|
||||
return;
|
||||
|
||||
var wrapperWindow = GetWindow(args.Context);
|
||||
if (wrapperWindow == null)
|
||||
return;
|
||||
|
||||
var callback = args.Callback;
|
||||
EventHandler handler = null;
|
||||
handler =
|
||||
(o, e) =>
|
||||
{
|
||||
wrapperWindow.Closed -= handler;
|
||||
wrapperWindow.Content = null;
|
||||
|
||||
if (_openedNotificationWindow != null && wrapperWindow is NotificationWindow)
|
||||
_openedNotificationWindow = null;
|
||||
|
||||
callback();
|
||||
};
|
||||
wrapperWindow.Closed += handler;
|
||||
|
||||
// New way, using StartupPosition enumeration:
|
||||
//
|
||||
if (StartupPosition == WindowPositions.CenterOwner || StartupPosition == WindowPositions.CenterScreen)
|
||||
{
|
||||
SizeChangedEventHandler sizeHandler = null;
|
||||
sizeHandler =
|
||||
(o, e) =>
|
||||
{
|
||||
wrapperWindow.SizeChanged -= sizeHandler;
|
||||
|
||||
if (StartupPosition == WindowPositions.CenterOwner)
|
||||
{
|
||||
var invoker = AssociatedObject;
|
||||
var position = invoker.PointToScreen(new Point(0, 0));
|
||||
wrapperWindow.Top = position.Y + ((invoker.ActualHeight - wrapperWindow.ActualHeight) / 2);
|
||||
wrapperWindow.Left = position.X + ((invoker.ActualWidth - wrapperWindow.ActualWidth) / 2);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapperWindow.Top = ((SystemParameters.WorkArea.Height - wrapperWindow.ActualHeight) / 2);
|
||||
wrapperWindow.Left = ((SystemParameters.WorkArea.Width - wrapperWindow.ActualWidth) / 2);
|
||||
}
|
||||
};
|
||||
wrapperWindow.SizeChanged += sizeHandler;
|
||||
}
|
||||
|
||||
// Old way, using CenterOverAssociatedObject property:
|
||||
//
|
||||
//if (CenterOverAssociatedObject)
|
||||
//{
|
||||
// SizeChangedEventHandler sizeHandler = null;
|
||||
// sizeHandler =
|
||||
// (o, e) =>
|
||||
// {
|
||||
// wrapperWindow.SizeChanged -= sizeHandler;
|
||||
|
||||
// FrameworkElement invoker = AssociatedObject;
|
||||
// Point position = invoker.PointToScreen(new Point(0, 0));
|
||||
|
||||
// wrapperWindow.Top = position.Y + ((invoker.ActualHeight - wrapperWindow.ActualHeight) / 2);
|
||||
// wrapperWindow.Left = position.X + ((invoker.ActualWidth - wrapperWindow.ActualWidth) / 2);
|
||||
// };
|
||||
// wrapperWindow.SizeChanged += sizeHandler;
|
||||
//}
|
||||
|
||||
|
||||
if (AllowMultipleNotificationWindows == false && wrapperWindow is NotificationWindow)
|
||||
_openedNotificationWindow = wrapperWindow;
|
||||
|
||||
if (IsModal)
|
||||
{
|
||||
wrapperWindow.ShowDialog();
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapperWindow.Show();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the WindowContent or its DataContext implements IPopupWindowActionAware and IRegionManagerAware.
|
||||
/// If so, it sets the corresponding values.
|
||||
/// Also, if WindowContent does not have a RegionManager attached, it creates a new scoped RegionManager for it.
|
||||
/// </summary>
|
||||
/// <param name="notification">The notification to be set as a DataContext in the HostWindow.</param>
|
||||
/// <param name="wrapperWindow">The HostWindow</param>
|
||||
protected void PrepareContentForWindow(Notification notification, Window wrapperWindow)
|
||||
{
|
||||
if (WindowContent == null)
|
||||
return;
|
||||
|
||||
// We set the WindowContent as the content of the window.
|
||||
wrapperWindow.Content = WindowContent;
|
||||
|
||||
var regionManager = WindowContent.GetValue(RegionManager.RegionManagerProperty) as IRegionManager;
|
||||
|
||||
// If the WindowContent does not have a RegionManager attached we create a new scoped RegionManager for it in order to support regions.
|
||||
if (regionManager == null)
|
||||
{
|
||||
regionManager = new RegionManager();
|
||||
WindowContent.SetValue(RegionManager.RegionManagerProperty, regionManager);
|
||||
}
|
||||
|
||||
// If the WindowContent implements IRegionManagerAware we set the new scoped manager as the RegionManager.
|
||||
var regionManagerAwareContent = WindowContent as IRegionManagerAware;
|
||||
if (regionManagerAwareContent != null)
|
||||
{
|
||||
regionManagerAwareContent.RegionManager = regionManager;
|
||||
}
|
||||
|
||||
// If the WindowContent's DataContext implements IRegionManagerAware we set the new scoped manager as the RegionManager.
|
||||
var regionManagerAwareDataContext = WindowContent.DataContext as IRegionManagerAware;
|
||||
if (regionManagerAwareDataContext != null)
|
||||
{
|
||||
regionManagerAwareDataContext.RegionManager = regionManager;
|
||||
}
|
||||
|
||||
// If the WindowContent implements IPopupWindowActionAware, we set the corresponding values.
|
||||
var popupAwareContent = WindowContent as IPopupWindowActionAware;
|
||||
if (popupAwareContent != null)
|
||||
{
|
||||
popupAwareContent.HostWindow = wrapperWindow;
|
||||
popupAwareContent.HostNotification = notification;
|
||||
}
|
||||
|
||||
// If the WindowContent's DataContext implements IPopupWindowActionAware, we set the corresponding values.
|
||||
var popupAwareDataContext = WindowContent.DataContext as IPopupWindowActionAware;
|
||||
if (popupAwareDataContext != null)
|
||||
{
|
||||
popupAwareDataContext.HostWindow = wrapperWindow;
|
||||
popupAwareDataContext.HostNotification = notification;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Window creation methods
|
||||
|
||||
/// <summary>
|
||||
/// Returns the window to display as part of the trigger action.
|
||||
/// </summary>
|
||||
/// <param name="notification">The notification to be set as a DataContext in the window.</param>
|
||||
/// <returns></returns>
|
||||
protected Window GetWindow(Notification notification)
|
||||
{
|
||||
Window wrapperWindow;
|
||||
|
||||
if (WindowContent != null)
|
||||
{
|
||||
wrapperWindow = new Window();
|
||||
|
||||
// If the WindowContent does not have its own DataContext, it will inherit this one.
|
||||
wrapperWindow.DataContext = notification;
|
||||
wrapperWindow.Title = notification.Title;
|
||||
|
||||
PrepareContentForWindow(notification, wrapperWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
wrapperWindow = CreateWindow(notification);
|
||||
}
|
||||
|
||||
return wrapperWindow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When no WindowContent is sent this method is used to create a Notification/Confirmation window to show
|
||||
/// the corresponding <see cref="Notification"/> or <see cref="Confirmation"/>.
|
||||
/// </summary>
|
||||
/// <param name="notification">The Notification or Confirmation parameter to show.</param>
|
||||
/// <returns></returns>
|
||||
protected Window CreateWindow(Notification notification)
|
||||
{
|
||||
Window window = null;
|
||||
|
||||
if (notification is Confirmation)
|
||||
{
|
||||
window = new ConfirmationWindow { ConfirmationTemplate = ContentTemplate };
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = notification.Content as NotificationContentEventArgs;
|
||||
if (content == null)
|
||||
return null;
|
||||
|
||||
var imageUri = GetImageUri(content.Image);
|
||||
window = new NotificationWindow { NotificationTemplate = ContentTemplate, ImageUri = imageUri };
|
||||
}
|
||||
|
||||
window.DataContext = notification;
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Uri"/> for the notification image.
|
||||
/// </summary>
|
||||
/// <param name="windowImage">The popup window's symbol.</param>
|
||||
private Uri GetImageUri(PopupWindowImage windowImage)
|
||||
{
|
||||
string image;
|
||||
|
||||
switch (windowImage)
|
||||
{
|
||||
case PopupWindowImage.Error:
|
||||
image = "error_48.png";
|
||||
break;
|
||||
case PopupWindowImage.Question:
|
||||
image = "question_48.png";
|
||||
break;
|
||||
case PopupWindowImage.Warning:
|
||||
image = "warning_48.png";
|
||||
break;
|
||||
case PopupWindowImage.Information:
|
||||
image = "information_48.png";
|
||||
break;
|
||||
default:
|
||||
image = "warning_48.png";
|
||||
break;
|
||||
}
|
||||
|
||||
return new Uri("pack://application:,,,/" + System.Reflection.Assembly.GetExecutingAssembly() + ";component/Images/" + image, UriKind.RelativeOrAbsolute);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace DTS.Common.Interface.TestSetups.Imports.TTS.HardwareScan
|
||||
{
|
||||
public interface IHardwareSummaryRecord
|
||||
{
|
||||
uint DOut { get; set; }
|
||||
uint DIn { get; set; }
|
||||
uint Squib { get; set; }
|
||||
uint Analog { get; set; }
|
||||
uint Total { get; }
|
||||
uint SPS { get; set; }
|
||||
uint SPD { get; set; }
|
||||
uint SPT { get; set; }
|
||||
uint ECM { get; set; }
|
||||
uint Rack { get; set; }
|
||||
uint G5 { get; set; }
|
||||
void UpdateTotal();
|
||||
|
||||
void Update(uint analog, uint squib, uint din, uint dout, uint ecm, uint sps, uint spt, uint spd, uint g5,
|
||||
uint rack);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Microsoft.Practices.Prism.Events;
|
||||
|
||||
|
||||
namespace DTS.Common.Events
|
||||
{
|
||||
/// <summary>
|
||||
/// sets the property UseZeroForUnfiltered
|
||||
/// this controls whether 0 or P is used in isocode filter field
|
||||
/// when modifying an isocode from a filter
|
||||
/// </summary>
|
||||
public class SetUseZeroForUnfilteredEvent : CompositePresentationEvent<bool> { }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using DTS.Common.Converters;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace DTS.Common.Enums.Viewer.Reports
|
||||
{
|
||||
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
|
||||
public enum WindowAveragingType
|
||||
{
|
||||
[Description("Averaging")]
|
||||
Averaging,
|
||||
[Description("Peak Hold MAX")]
|
||||
PeakHoldMax,
|
||||
[Description("Peak Hold MIN")]
|
||||
PeakHoldMin,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Interactivity;
|
||||
|
||||
namespace DTS.Common.Behaviors
|
||||
{
|
||||
|
||||
public class TrimTextBoxBehavior : Behavior<TextBox>
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
base.OnAttached();
|
||||
|
||||
AssociatedObject.LostFocus += AssociatedObject_LostFocus;
|
||||
|
||||
}
|
||||
|
||||
private void AssociatedObject_LostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var trim = AssociatedObject.Text.Trim();
|
||||
if (trim != AssociatedObject.Text)
|
||||
{
|
||||
AssociatedObject.Text = trim;
|
||||
AssociatedObject.GetBindingExpression(TextBox.TextProperty).UpdateSource();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetaching()
|
||||
{
|
||||
base.OnDetaching();
|
||||
|
||||
AssociatedObject.LostFocus -= AssociatedObject_LostFocus;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.Base;
|
||||
using Microsoft.Practices.Prism.Regions;
|
||||
// ReSharper disable InconsistentNaming
|
||||
// ReSharper disable CheckNamespace
|
||||
|
||||
namespace DTS.Common
|
||||
{
|
||||
public interface IDTSViewRegionManager : IRegionManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds View to the Main Region.
|
||||
/// </summary>
|
||||
/// <param name="viewDefinition">The View definition.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the View.</param>
|
||||
void AddView(ViewDefinition viewDefinition, object parameter);
|
||||
|
||||
/// <summary>
|
||||
/// Adds View to the Main Region.
|
||||
/// </summary>
|
||||
/// <param name="viewDefinition">The View definition.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the View.</param>
|
||||
/// <param name="allowMultipleInstances">A value indicating whether to allow to create the multiple views.</param>
|
||||
void AddView(ViewDefinition viewDefinition, object parameter, bool allowMultipleInstances);
|
||||
|
||||
/// <summary>
|
||||
/// Adds View to the Main Region asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="viewDefinition">The View definition.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the service.</param>
|
||||
Task AddViewAsync(ViewDefinition viewDefinition, object parameter);
|
||||
|
||||
/// <summary>
|
||||
/// Adds View to the Main Region asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="viewDefinition">The View definition.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the View.</param>
|
||||
/// <param name="allowMultipleInstances">A value indicating whether to allow to create the multiple views.</param>
|
||||
Task AddViewAsync(ViewDefinition viewDefinition, object parameter, bool allowMultipleInstances);
|
||||
|
||||
/// <summary>
|
||||
/// Removes View from the Main Region.
|
||||
/// </summary>
|
||||
/// <param name="viewModel">The View-model.</param>
|
||||
void RemoveView(IBaseViewModel viewModel);
|
||||
|
||||
/// <summary>
|
||||
/// Removes View from the specified region by name
|
||||
/// </summary>
|
||||
/// <param name="regionName"></param>
|
||||
void RemoveViewByRegionName(string regionName);
|
||||
|
||||
/// <summary>
|
||||
/// Reloads data for the specified View.
|
||||
/// </summary>
|
||||
/// <param name="interfaceForView">Type of the View's interface.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the View.</param>
|
||||
void RefreshView(Type interfaceForView, object parameter);
|
||||
|
||||
/// <summary>
|
||||
/// Reloads data for the specified View asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="interfaceForView">Type of the View's interface.</param>
|
||||
/// <param name="parameter">The parameter which uses to initialize the View.</param>
|
||||
Task RefreshViewAsync(Type interfaceForView, object parameter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace DTS.Common.Classes.WindowsFolders
|
||||
{
|
||||
public class WindowsFolder
|
||||
{
|
||||
/// <summary>
|
||||
/// Open the folder containing all of the manuals. The default path is C:\DTS\DTS.Suite\(version)\DataPRO\Manuals,
|
||||
/// but this function assumes that the Manuals folder is in the CurrentDirectory, which is always the case
|
||||
/// (even when DataPRO is installed in a non-default location).
|
||||
/// </summary>
|
||||
public static void OpenManualsFolder(string path)
|
||||
{
|
||||
var manualsPath = Path.Combine(path, Constants.ManualsFolder);
|
||||
|
||||
Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
FileName = Constants.WindowsExplorer,
|
||||
Arguments = manualsPath
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user