diff options
| author | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-22 07:01:05 +0300 |
|---|---|---|
| committer | Roy Ben Shabat <Roy.mail.net@gmail.com> | 2020-04-22 07:01:05 +0300 |
| commit | 405f1ac07d78468c3e1a0ef1c0dc8956635c8677 (patch) | |
| tree | e7103eb16188663d28f0926b94eaabd87fb2473b | |
| parent | 499e0a03bb41e2330a47ccca83e6e6dfe7c5a634 (diff) | |
| download | Tango-405f1ac07d78468c3e1a0ef1c0dc8956635c8677.tar.gz Tango-405f1ac07d78468c3e1a0ef1c0dc8956635c8677.zip | |
FSE work + fixed issue with personal access token on MS and PPC.
28 files changed, 459 insertions, 61 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml new file mode 100644 index 000000000..7ae84ff9e --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml @@ -0,0 +1,36 @@ +<UserControl x:Class="Tango.FSE.Stubs.Dialogs.AddReferenceAssemblyView" + xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:local="clr-namespace:Tango.FSE.Stubs.Dialogs" + mc:Ignorable="d" + Width="1000" Height="600" d:DataContext="{d:DesignInstance Type=local:AddReferenceAssemblyViewVM, IsDesignTimeCreatable=False}" Background="{StaticResource FSE_PrimaryBackgroundLightBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + <Grid Margin="10"> + <DockPanel> + <StackPanel DockPanel.Dock="Top" Orientation="Horizontal"> + <material:PackIcon Kind="LibraryEdit" Width="32" Height="32" /> + <TextBlock Margin="10 0 0 0" FontSize="{StaticResource FSE_LargeFontSize}" VerticalAlignment="Center">Reference Assemblies</TextBlock> + </StackPanel> + + <Border Margin="0 20 0 0" BorderThickness="1" BorderBrush="{StaticResource FSE_BorderBrush}" Background="{StaticResource FSE_PrimaryBackgroundDarkBrush}" CornerRadius="5"> + <ScrollViewer Margin="2" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled"> + <ItemsControl ItemsSource="{Binding ReferenceAssemblies}"> + <ItemsControl.ItemTemplate> + <DataTemplate> + <Border Padding="5"> + <StackPanel Orientation="Horizontal"> + <CheckBox VerticalAlignment="Center" IsChecked="{Binding IsSelected,Mode=TwoWay}" /> + <material:PackIcon Margin="5 0 0 0" VerticalAlignment="Center" Kind="Library" Width="20" Height="20" /> + <TextBlock Margin="10 0 0 0" Text="{Binding Data.Name}" VerticalAlignment="Center"></TextBlock> + </StackPanel> + </Border> + </DataTemplate> + </ItemsControl.ItemTemplate> + </ItemsControl> + </ScrollViewer> + </Border> + </DockPanel> + </Grid> +</UserControl> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml.cs new file mode 100644 index 000000000..5bfd20b5f --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Tango.FSE.Stubs.Dialogs +{ + /// <summary> + /// Interaction logic for AddReferenceAssemblyView.xaml + /// </summary> + public partial class AddReferenceAssemblyView : UserControl + { + public AddReferenceAssemblyView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyViewVM.cs new file mode 100644 index 000000000..0f79da8d6 --- /dev/null +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Dialogs/AddReferenceAssemblyViewVM.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.Core.Helpers; +using Tango.FSE.Common; +using Tango.FSE.Common.FSEApplication; +using Tango.Scripting.Basic; +using Tango.SharedUI.Components; + +namespace Tango.FSE.Stubs.Dialogs +{ + public class AddReferenceAssemblyViewVM : FSEDialogViewVM + { + [TangoInject] + private IFSEApplicationManager ApplicationManager { get; set; } + + public SelectedObjectCollection<ReferenceAssembly> ReferenceAssemblies { get; set; } + + public AddReferenceAssemblyViewVM(List<ReferenceAssembly> existing) + { + OKText = "ADD"; + + TangoIOC.Default.Inject(this); + + List<ReferenceAssembly> source = new List<ReferenceAssembly>(); + + var startPath = ApplicationManager.StartPath; + + foreach (var file in Directory.GetFiles(startPath, "*.dll")) + { + source.Add(ReferenceAssembly.FromFile(Path.GetFileName(file))); + } + + String dotNetVersion = AssemblyHelper.GetTargetFrameworkVersion(Assembly.GetExecutingAssembly()).ToString(); + String dotNetPath = $@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v{dotNetVersion}"; + + foreach (var file in Directory.GetFiles(dotNetPath, "*.dll")) + { + source.Add(ReferenceAssembly.FromFile(Path.GetFileName(file))); + } + + source = source.DistinctBy(x => x.Name).ToList(); + + List<ReferenceAssembly> existingReferences = new List<ReferenceAssembly>(); + + foreach (var asm in source) + { + if (existing.Exists(x => x.Name == asm.Name)) + { + existingReferences.Add(asm); + } + } + + ReferenceAssemblies = new SelectedObjectCollection<ReferenceAssembly>(source.ToObservableCollection(), existingReferences.ToObservableCollection()); + } + } +} diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs index 41b13f2d2..9b8eb6f06 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ITestContext.cs @@ -18,7 +18,9 @@ namespace Tango.FSE.Stubs void RemoveResult(Result result); void ClearResults(); IMessage Run(String stubName, params Object[] args); + T Run<T>(String stubName, params Object[] args) where T : class, IMessage; IMessage Run(IMessage stub); + T Run<T>(IMessage stub) where T : class, IMessage; void RunContinuous<T>(T stub, Action<T> callback) where T : class, IMessage; void RunContinuous<T>(String stubName, Action<T> callback, params Object[] args) where T : class, IMessage; void WriteLine(Object obj); diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs index de93305d8..3e3bddece 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ProjectRunner.cs @@ -12,6 +12,8 @@ namespace Tango.FSE.Stubs { private ProjectSession<ITestContext> _currentSession; + public event EventHandler<ProjectRunnerState> StateChanged; + private ProjectRunnerState _state; public ProjectRunnerState State { @@ -24,6 +26,8 @@ namespace Tango.FSE.Stubs RaisePropertyChanged(nameof(IsCompiling)); RaisePropertyChanged(nameof(CanRun)); RaisePropertyChanged(nameof(CanCompile)); + + StateChanged?.Invoke(this, value); } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx index c50f70c5f..56f1974ff 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Resources/main_template.csx @@ -5,6 +5,8 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using Google.Protobuf; +using Tango.PMR.Stubs; using Tango.FSE.Stubs; public class Program diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj index faf3615be..54d6f3507 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Tango.FSE.Stubs.csproj @@ -97,6 +97,10 @@ <ItemGroup> <Compile Include="Designer\ProjectModel.cs" /> <Compile Include="Designer\ScriptTabModel.cs" /> + <Compile Include="Dialogs\AddReferenceAssemblyView.xaml.cs"> + <DependentUpon>AddReferenceAssemblyView.xaml</DependentUpon> + </Compile> + <Compile Include="Dialogs\AddReferenceAssemblyViewVM.cs" /> <Compile Include="ITestContext.cs" /> <Compile Include="ITestLogger.cs" /> <Compile Include="ProjectRunner.cs" /> @@ -211,6 +215,10 @@ <Generator>MSBuild:Compile</Generator> <SubType>Designer</SubType> </Page> + <Page Include="Dialogs\AddReferenceAssemblyView.xaml"> + <SubType>Designer</SubType> + <Generator>MSBuild:Compile</Generator> + </Page> <Page Include="Themes\Generic.xaml"> <SubType>Designer</SubType> <Generator>MSBuild:Compile</Generator> diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs index 83823a27c..909b026d6 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/TestContext.cs @@ -23,7 +23,7 @@ namespace Tango.FSE.Stubs private ITestLogger _logger; [TangoInject] - private IMachineProvider MachineProvider; + private IMachineProvider MachineProvider { get; set; } [TangoInject] private INotificationProvider NotificationProvider { get; set; } @@ -37,6 +37,7 @@ namespace Tango.FSE.Stubs { _logger = logger; Results = new ReadOnlyCollection<Result>(new List<Result>()); + TangoIOC.Default.Inject(this); } public IMessage Run(string stubName, params object[] args) @@ -83,11 +84,21 @@ namespace Tango.FSE.Stubs return Run(request as IMessage); } + public T Run<T>(string stubName, params object[] args) where T : class, IMessage + { + return Run(stubName, args) as T; + } + public IMessage Run(IMessage stub) { return MachineProvider.MachineOperator.SendRequest(stub, new Transport.TransportRequestConfig()).Result; } + public T Run<T>(IMessage stub) where T : class, IMessage + { + return Run(stub) as T; + } + public void RunContinuous<T>(T stub, Action<T> callback) where T : class, IMessage { Type stubType = stub.GetType(); diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs index d87fe0ff3..a63469f14 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/ViewModels/TestDesignerViewVM.cs @@ -10,6 +10,7 @@ using Tango.Core; using Tango.Core.Commands; using Tango.Core.ExtensionMethods; using Tango.FSE.Common; +using Tango.FSE.Stubs.Dialogs; using Tango.Integration.Operation; using Tango.Scripting.Basic; using Tango.Scripting.Editors; @@ -28,6 +29,8 @@ namespace Tango.FSE.Stubs.ViewModels Results } + #region Properties + private ToolWindows _selectedToolWindow; public ToolWindows SelectedToolWindow { @@ -56,6 +59,13 @@ namespace Tango.FSE.Stubs.ViewModels set { _compilationErrors = value; RaisePropertyChangedAuto(); } } + private List<Result> _results; + public List<Result> Results + { + get { return _results; } + set { _results = value; RaisePropertyChangedAuto(); } + } + public ObservableCollection<Script> OpenScripts { get; set; } private Script _selectedScript; @@ -81,18 +91,27 @@ namespace Tango.FSE.Stubs.ViewModels set { _cacheProgress = value; RaisePropertyChangedAuto(); } } - private bool _isCaching; + private bool _isLoadingSymbols; public bool IsLoadingSymbols { - get { return _isCaching; } - set { _isCaching = value; RaisePropertyChangedAuto(); } + get { return _isLoadingSymbols; } + set { _isLoadingSymbols = value; RaisePropertyChangedAuto(); } } + #endregion + + #region Commands + public RelayCommand<Script> OpenScriptCommand { get; set; } public RelayCommand<Script> CloseScriptCommand { get; set; } public RelayCommand RunProjectCommand { get; set; } public RelayCommand StopProjectCommand { get; set; } public RelayCommand CompileProjectCommand { get; set; } + public RelayCommand AddReferenceAssemblyCommand { get; set; } + + #endregion + + #region Constructors public TestDesignerViewVM() { @@ -104,17 +123,23 @@ namespace Tango.FSE.Stubs.ViewModels ScriptEditor.LoadingSymbolsStarted += ScriptEditor_LoadingSymbolsStarted; ScriptEditor.LoadingSymbolsCompleted += ScriptEditor_LoadingSymbolsCompleted; ScriptEditor.BlockedUsingsCache.Add("Tango.FSE.Stubs"); + ScriptEditor.BlockedUsingsCache.Add("Tango.PMR.Stubs"); OpenScripts = new ObservableCollection<Script>(); OpenScriptCommand = new RelayCommand<Script>(OpenScript); CloseScriptCommand = new RelayCommand<Script>(CloseScript); - RunProjectCommand = new RelayCommand(RunProject); - StopProjectCommand = new RelayCommand(StopProject); - CompileProjectCommand = new RelayCommand(async () => await CompileProject()); + RunProjectCommand = new RelayCommand(RunProject, () => ProjectRunner != null && ProjectRunner.CanRun); + StopProjectCommand = new RelayCommand(StopProject, () => ProjectRunner != null && ProjectRunner.IsRunning); + CompileProjectCommand = new RelayCommand(async () => await CompileProject(), () => ProjectRunner != null && ProjectRunner.CanCompile); + AddReferenceAssemblyCommand = new RelayCommand(AddReferenceAssembly); CreateNewProject(); } + #endregion + + #region Script Editor Symbols Loading Handlers + private void ScriptEditor_LoadingSymbolsCompleted(object sender, EventArgs e) { IsLoadingSymbols = false; @@ -130,6 +155,10 @@ namespace Tango.FSE.Stubs.ViewModels SymbolsLoadingProgress = e.Progress; } + #endregion + + #region Project Start/Stop Compile + private void StopProject() { ProjectRunner.Stop(); @@ -186,12 +215,15 @@ namespace Tango.FSE.Stubs.ViewModels if (await CompileProject()) { SelectedToolWindow = ToolWindows.Output; + Results = new List<Result>(); Logger.Clear(); Logger.WriteLine("Running project..."); var context = new TestContext(this); await ProjectRunner.Run(context); Logger.WriteLine("Project ran to completion with test result:"); Logger.WriteLine(context.Results.ToJsonString()); + Results = context.Results.ToList(); + SelectedToolWindow = ToolWindows.Results; } } catch (OperationCanceledException) @@ -202,10 +234,14 @@ namespace Tango.FSE.Stubs.ViewModels { SelectedToolWindow = ToolWindows.Output; Logger.WriteLine("Project terminated with error:"); - Logger.WriteLine(ex.FlattenException()); + Logger.WriteLine(ex.FlattenMessage()); } } + #endregion + + #region Open/Close Script Tabs + private void CloseScript(Script script) { script.IsSelected = false; @@ -223,17 +259,44 @@ namespace Tango.FSE.Stubs.ViewModels SelectedScript = script; } + #endregion + + #region Event Handlers + + private void ProjectRunner_StateChanged(object sender, ProjectRunnerState e) + { + InvalidateRelayCommands(); + } + + #endregion + + #region Private Methods + + private async void AddReferenceAssembly() + { + var vm = await NotificationProvider.ShowDialog<AddReferenceAssemblyViewVM>(new AddReferenceAssemblyViewVM(Project.ReferenceAssemblies.ToList())); + if (vm.DialogResult) + { + Project.ReferenceAssemblies.Clear(); + + foreach (var asm in vm.ReferenceAssemblies.SynchedSource) + { + Project.ReferenceAssemblies.Add(asm); + } + } + } + private void CreateNewProject() { var project = Project<ITestContext>.New("test1"); project.Scripts.Add(Script.New("Program.csx", Encoding.UTF8.GetString(Properties.Resources.main_template), true)); project.Scripts.Add(Script.New("lib.csx", Encoding.UTF8.GetString(Properties.Resources.lib_template))); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = this.GetType() }); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(PMR.Common.MessageType) }); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(ITransporter) }); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(IMachineOperator) }); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(IMessage) }); - project.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(System.Drawing.Point) }); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(this.GetType())); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(PMR.Common.MessageType))); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(ITransporter))); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(IMachineOperator))); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(IMessage))); + project.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(System.Drawing.Point))); Project = project; } @@ -243,13 +306,20 @@ namespace Tango.FSE.Stubs.ViewModels if (Project != null) { ProjectRunner = new ProjectRunner(Project); + ProjectRunner.StateChanged += ProjectRunner_StateChanged; } else { ProjectRunner = null; } + + InvalidateRelayCommands(); } + #endregion + + #region ITestLogger + public void WriteLine(string text) { Logger.WriteLine(text); @@ -264,5 +334,7 @@ namespace Tango.FSE.Stubs.ViewModels { Logger.Clear(); } + + #endregion } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml index 467d106f7..47df50d24 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Stubs/Views/TestDesignerView.xaml @@ -13,6 +13,12 @@ xmlns:local="clr-namespace:Tango.FSE.Stubs.Views" mc:Ignorable="d" d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:TestDesignerViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.TestDesignerViewVM}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + + <UserControl.InputBindings> + <KeyBinding Key="F5" Command="{Binding RunProjectCommand}" /> + <KeyBinding Key="F6" Command="{Binding CompileProjectCommand}" /> + </UserControl.InputBindings> + <Grid> <Grid> <DockPanel> @@ -58,7 +64,7 @@ </MenuItem> </MenuItem> <MenuItem Header="Debug"> - <MenuItem Header="_Build" Command="{Binding CompileProjectCommand}" InputGestureText="Shift+F6" IsEnabled="{Binding ProjectRunner.CanCompile}"> + <MenuItem Header="_Build" Command="{Binding CompileProjectCommand}" InputGestureText="F6" IsEnabled="{Binding ProjectRunner.CanCompile}"> <MenuItem.Icon> <material:PackIcon Kind="PackageDown" /> </MenuItem.Icon> @@ -298,8 +304,43 @@ </DataGrid.Columns> </DataGrid> </TabItem> - <TabItem Header="RESULT"> - + <TabItem> + <TabItem.Header> + <TextBlock> + <Run>RESULTS</Run> + <Run>(</Run><Run Text="{Binding Results.Count,Mode=OneWay}"></Run><Run>)</Run> + </TextBlock> + </TabItem.Header> + <DataGrid ItemsSource="{Binding Results}" Style="{StaticResource FSE_LogsGridStyle}" CellStyle="{StaticResource FSE_LogsGridCellStyle}" HorizontalGridLinesBrush="{StaticResource FSE_PrimaryBackgroundBrush}" AutoGenerateColumns="False"> + <DataGrid.Columns> + <DataGridTemplateColumn Width="40"> + <DataGridTemplateColumn.CellTemplate> + <DataTemplate> + <material:PackIcon HorizontalAlignment="Center" VerticalAlignment="Center"> + <material:PackIcon.Style> + <Style TargetType="material:PackIcon"> + <Setter Property="Kind" Value="Check"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_SuccessBrush}"></Setter> + <Style.Triggers> + <DataTrigger Binding="{Binding Type}" Value="Warning"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_WarningBrush}"></Setter> + </DataTrigger> + <DataTrigger Binding="{Binding Type}" Value="Failed"> + <Setter Property="Kind" Value="Alert"></Setter> + <Setter Property="Foreground" Value="{StaticResource FSE_ErrorBrush}"></Setter> + </DataTrigger> + </Style.Triggers> + </Style> + </material:PackIcon.Style> + </material:PackIcon> + </DataTemplate> + </DataGridTemplateColumn.CellTemplate> + </DataGridTemplateColumn> + <DataGridTextColumn Header="NAME" Binding="{Binding Name}" /> + <DataGridTextColumn Header="VALUE" Binding="{Binding Value}" Width="1*" /> + </DataGrid.Columns> + </DataGrid> </TabItem> <TabItem Header="PUBLISH"> @@ -326,7 +367,17 @@ <DockPanel Margin="5 10 0 0"> <controls:ToggleIconButton Width="20" Height="20" x:Name="chkReference" UncheckedIcon="ChevronRight" CheckedIcon="ChevronDown" Cursor="Hand" IsChecked="True" /> - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center">Reference Assemblies</TextBlock> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="Reference Assemblies"> + <TextBlock.ContextMenu> + <ContextMenu> + <MenuItem Header="Add Reference" Command="{Binding AddReferenceAssemblyCommand}"> + <MenuItem.Icon> + <material:PackIcon Kind="LibraryEdit" /> + </MenuItem.Icon> + </MenuItem> + </ContextMenu> + </TextBlock.ContextMenu> + </TextBlock> </DockPanel> <ListBox Margin="25 5 0 0" ItemsSource="{Binding Project.ReferenceAssemblies}" Visibility="{Binding ElementName=chkReference,Path=IsChecked,Converter={StaticResource BooleanToVisibilityConverter}}"> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/BugReportView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/BugReportView.xaml index ce365d828..44048f4fd 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/BugReportView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Dialogs/BugReportView.xaml @@ -31,7 +31,7 @@ <material:PackIcon Kind="Pencil" /> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" FontSize="{StaticResource FSE_SmallFontSize}">What Happened ?</TextBlock> </DockPanel> - <TextBox Background="{StaticResource FSE_PrimaryBackgroundBrush}" IsEnabled="{Binding IsEditable}" Text="{Binding Bug.Description,UpdateSourceTrigger=PropertyChanged}" Margin="0 3 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox_Multiline}" AcceptsReturn="True" Height="200"></TextBox> + <TextBox Background="{StaticResource FSE_PrimaryBackgroundBrush}" IsEnabled="{Binding IsEditable}" Text="{Binding Bug.Description,UpdateSourceTrigger=PropertyChanged}" Margin="0 3 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox_Multiline}" AcceptsReturn="True" TextWrapping="Wrap" Height="200"></TextBox> </StackPanel> </StackPanel> @@ -40,7 +40,7 @@ <material:PackIcon Kind="UserAlertOutline" /> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" FontSize="{StaticResource FSE_SmallFontSize}">Additional Comments</TextBlock> </DockPanel> - <TextBox Text="{Binding Bug.Comments,UpdateSourceTrigger=PropertyChanged}" Margin="0 2 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox_Multiline}" AcceptsReturn="True"></TextBox> + <TextBox TextWrapping="Wrap" Text="{Binding Bug.Comments,UpdateSourceTrigger=PropertyChanged}" Margin="0 2 0 0" Style="{StaticResource FSE_Rounded_Corners_TextBox_Multiline}" AcceptsReturn="True"></TextBox> </DockPanel> </DockPanel> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs index bfd5b0557..7b1727ec3 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/TFS/TeamFoundationServiceExtendedClient.cs @@ -245,14 +245,18 @@ namespace Tango.MachineStudio.UI.TFS if (MachineOperator.EnableSessionLogFile) { var file = MachineOperator.SessionLogger.LogFile; - var sessionLogFile = _tempFolder.CreateImaginaryFile(); - File.Copy(file, sessionLogFile.Path); - item.Attachments.Add(new Attachment() + + if (file != null && File.Exists(file)) { - Description = "Session Log File", - FilePath = sessionLogFile.Path, - Name = Path.GetFileName(file), - }); + var sessionLogFile = _tempFolder.CreateImaginaryFile(); + File.Copy(file, sessionLogFile.Path); + item.Attachments.Add(new Attachment() + { + Description = "Session Log File", + FilePath = sessionLogFile.Path, + Name = Path.GetFileName(file), + }); + } } SystemInformationModel sysModel = new SystemInformationModel(); diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs index 9539037f1..e0338a319 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModelLocator.cs @@ -96,7 +96,7 @@ namespace Tango.MachineStudio.UI TangoIOC.Default.Register<ISpeechProvider, DefaultSpeechProvider>(); TangoIOC.Default.Register<IFirmwareUpgrader, DefaultFirmwareUpgrader>(); TangoIOC.Default.Register<IActionLogManager, DefaultActionLogManager>(new DefaultActionLogManager() { IsAsync = true }); - TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); + TangoIOC.Default.Register<TeamFoundationServiceExtendedClient>(new TeamFoundationServiceExtendedClient("https://twinetfs.visualstudio.com", String.Empty, "pyulwgs7m3v7pizz3oxusypdkdfw43txggo5mjwu2ouyv2qwprhq")); TangoIOC.Default.Register<MainViewVM>(); diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/TFS/TeamFoundationServicePPCClient.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/TFS/TeamFoundationServicePPCClient.cs index eb5b8f283..8a597ef61 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/TFS/TeamFoundationServicePPCClient.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/TFS/TeamFoundationServicePPCClient.cs @@ -138,14 +138,18 @@ namespace Tango.PPC.BugReporting.TFS if (MachineOperator.EnableSessionLogFile) { var file = MachineOperator.SessionLogger.LogFile; - var sessionLogFile = tempFolder.CreateImaginaryFile(); - File.Copy(file, sessionLogFile.Path); - item.Attachments.Add(new Attachment() + + if (file != null && File.Exists(file)) { - Description = "Session Log File", - FilePath = sessionLogFile.Path, - Name = Path.GetFileName(file), - }); + var sessionLogFile = tempFolder.CreateImaginaryFile(); + File.Copy(file, sessionLogFile.Path); + item.Attachments.Add(new Attachment() + { + Description = "Session Log File", + FilePath = sessionLogFile.Path, + Name = Path.GetFileName(file), + }); + } } SystemInformationModel sysModel = new SystemInformationModel(); diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/ViewModelLocator.cs index 1f71ca2c1..24b222370 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.BugReporting/ViewModelLocator.cs @@ -16,7 +16,7 @@ namespace Tango.PPC.BugReporting /// </summary> static ViewModelLocator() { - TangoIOC.Default.Register<TeamFoundationServicePPCClient>(new TeamFoundationServicePPCClient("https://twinetfs.visualstudio.com", String.Empty, "szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa")); + TangoIOC.Default.Register<TeamFoundationServicePPCClient>(new TeamFoundationServicePPCClient("https://twinetfs.visualstudio.com", String.Empty, "pyulwgs7m3v7pizz3oxusypdkdfw43txggo5mjwu2ouyv2qwprhq")); TangoIOC.Default.Register<MainViewVM>(); } diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs index 85caf4706..14a9d94da 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/Project.cs @@ -73,9 +73,9 @@ namespace Tango.Scripting.Basic { ReferenceAssembliesLoaded.Clear(); - foreach (var type in ReferenceAssemblies) + foreach (var asm in ReferenceAssemblies) { - ReferenceAssembliesLoaded.Add(type.FromType.Assembly); + ReferenceAssembliesLoaded.Add(Assembly.LoadFrom(asm.File)); } } @@ -85,10 +85,10 @@ namespace Tango.Scripting.Basic p.Name = name; - p.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(String) }); - p.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(Enumerable) }); - p.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(Form) }); - p.ReferenceAssemblies.Add(new ReferenceAssembly() { FromType = typeof(Project<T>) }); + p.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(String))); + p.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(Enumerable))); + p.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(Form))); + p.ReferenceAssemblies.Add(ReferenceAssembly.FromType(typeof(Project<T>))); return p; } diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/ReferenceAssembly.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/ReferenceAssembly.cs index be66e026b..4b04270c1 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/ReferenceAssembly.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Basic/ReferenceAssembly.cs @@ -1,5 +1,7 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,11 +10,25 @@ namespace Tango.Scripting.Basic { public class ReferenceAssembly { - public Type FromType { get; set; } + public String File { get; set; } + [JsonIgnore] public String Name { - get { return FromType.Assembly.GetName().Name; } + get { return Path.GetFileNameWithoutExtension(File); } + } + + public static ReferenceAssembly FromType(Type type) + { + ReferenceAssembly reference = new ReferenceAssembly(); + var assembly = type.Assembly; + reference.File = assembly.Location; + return reference; + } + + public static ReferenceAssembly FromFile(String file) + { + return new ReferenceAssembly() { File = file }; } } } diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs index 7accdbb83..e9cb8fc4c 100644 --- a/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs +++ b/Software/Visual_Studio/Scripting/Tango.Scripting/Parsing/ScriptParser.cs @@ -131,16 +131,32 @@ namespace Tango.Scripting.Parsing if (prop != null) { - vars.Add(new ScriptSymbol() + var type = ReplaceFakeScript(prop.GetValue(symbol).ToString()); + + ScriptSymbol varSymbol = new ScriptSymbol(); + varSymbol.Name = symbol.Name; + varSymbol.Type = type; + varSymbol.Class = ReplaceFakeScript(symbol.ContainingType?.Name); + varSymbol.Kind = symbol.Kind; + varSymbol.Accessibility = symbol.DeclaredAccessibility; + varSymbol.ContainingNamespace = ReplaceFakeScript(symbol.ContainingNamespace?.Name); + varSymbol.Summary = GetSymbolDocumentation(symbol); + vars.Add(varSymbol); + + if (type == "?") { - Name = symbol.Name, - Type = ReplaceFakeScript(prop.GetValue(symbol).ToString()), - Class = ReplaceFakeScript(symbol.ContainingType?.Name), - Kind = symbol.Kind, - Accessibility = symbol.DeclaredAccessibility, - ContainingNamespace = ReplaceFakeScript(symbol.ContainingNamespace?.Name), - Summary = GetSymbolDocumentation(symbol), - }); + try + { + var variables = GetScriptVariables(code); + var variable = variables.FirstOrDefault(x => x.Name == symbol.Name); + + if (variable != null) + { + varSymbol.Type = variable.Type; + } + } + catch { } + } } } } @@ -392,5 +408,62 @@ namespace Tango.Scripting.Parsing var ret = root.ToFullString(); return ret; } + + private List<ScriptVariable> GetScriptVariables(String code) + { + List<ScriptVariable> vars = new List<ScriptVariable>(); + + SyntaxTree tree = CSharpSyntaxTree.ParseText(code); + var root = (CompilationUnitSyntax)tree.GetRoot(); + + List<VariableDeclaratorSyntax> variables = new List<VariableDeclaratorSyntax>(); + FillVariables(variables, root.Members[0]); + variables = variables.Distinct().ToList(); + + foreach (var item in variables) + { + ScriptVariable v = new ScriptVariable(); + v.Name = item.Identifier.ToString(); + + if (item.Initializer.Value.GetType() == typeof(ObjectCreationExpressionSyntax)) + { + v.Type = (item.Initializer.Value as ObjectCreationExpressionSyntax).Type.ToString(); + } + else if (item.Initializer.Value.GetType() == typeof(InvocationExpressionSyntax)) + { + v.Type = (((item.Initializer.Value as InvocationExpressionSyntax).Expression as MemberAccessExpressionSyntax).Name as GenericNameSyntax).TypeArgumentList.Arguments[0].ToString(); + } + + vars.Add(v); + } + + return vars; + } + + private void FillVariables(List<VariableDeclaratorSyntax> variables, SyntaxNode node) + { + foreach (var item in node.DescendantNodes(x => true)) + { + if (item.GetType() == typeof(VariableDeclaratorSyntax)) + { + variables.Add(item as VariableDeclaratorSyntax); + } + else + { + FillVariables(variables, item); + } + } + } + + private class ScriptVariable + { + public String Name { get; set; } + public String Type { get; set; } + + public override string ToString() + { + return String.Format("{0} : {1}", Type, Name); + } + } } } diff --git a/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs b/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs index 11ef751e2..59d36533e 100644 --- a/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs +++ b/Software/Visual_Studio/Tango.Core/Helpers/AssemblyHelper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Versioning; using System.Text; using System.Threading.Tasks; @@ -52,5 +53,13 @@ namespace Tango.Core.Helpers { return assembly.GetName().Version; } + + public static Version GetTargetFrameworkVersion(Assembly assembly) + { + object[] list = Assembly.GetExecutingAssembly().GetCustomAttributes(true); + var attribute = list.OfType<TargetFrameworkAttribute>().First(); + + return Version.Parse(attribute.FrameworkName.Replace(".NETFramework,Version=v", "")); + } } } diff --git a/Software/Visual_Studio/Tango.Stubs/Images/PinClose_Black.png b/Software/Visual_Studio/Tango.Stubs/Images/PinClose_Black.png Binary files differnew file mode 100644 index 000000000..abf709cb5 --- /dev/null +++ b/Software/Visual_Studio/Tango.Stubs/Images/PinClose_Black.png diff --git a/Software/Visual_Studio/Tango.Stubs/Images/pubclass.gif b/Software/Visual_Studio/Tango.Stubs/Images/pubclass.gif Binary files differnew file mode 100644 index 000000000..28abc36a7 --- /dev/null +++ b/Software/Visual_Studio/Tango.Stubs/Images/pubclass.gif diff --git a/Software/Visual_Studio/Tango.Stubs/Images/pubevent.gif b/Software/Visual_Studio/Tango.Stubs/Images/pubevent.gif Binary files differnew file mode 100644 index 000000000..7c2466f0e --- /dev/null +++ b/Software/Visual_Studio/Tango.Stubs/Images/pubevent.gif diff --git a/Software/Visual_Studio/Tango.Stubs/Images/pubmethod.gif b/Software/Visual_Studio/Tango.Stubs/Images/pubmethod.gif Binary files differnew file mode 100644 index 000000000..040280d15 --- /dev/null +++ b/Software/Visual_Studio/Tango.Stubs/Images/pubmethod.gif diff --git a/Software/Visual_Studio/Tango.Stubs/Images/pubproperty.gif b/Software/Visual_Studio/Tango.Stubs/Images/pubproperty.gif Binary files differnew file mode 100644 index 000000000..49d5042b9 --- /dev/null +++ b/Software/Visual_Studio/Tango.Stubs/Images/pubproperty.gif diff --git a/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj b/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj index 80c63b5d4..32efb0b32 100644 --- a/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj +++ b/Software/Visual_Studio/Tango.Stubs/Tango.Stubs.csproj @@ -195,10 +195,25 @@ <SubType>Designer</SubType> </Page> </ItemGroup> + <ItemGroup> + <Resource Include="Images\PinClose_Black.png" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\pubclass.gif" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\pubevent.gif" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\pubmethod.gif" /> + </ItemGroup> + <ItemGroup> + <Resource Include="Images\pubproperty.gif" /> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <ProjectExtensions> <VisualStudio> - <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" /> + <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" /> </VisualStudio> </ProjectExtensions> </Project>
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs index 27d93f467..bb3ef588f 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs @@ -117,8 +117,8 @@ namespace Tango.MachineService.Controllers { return new BugReportingInfoResponse() { - CollectionUrl = MachineServiceConfig.FSE_TFS_COLLECTION_URL, - PersonalToken = MachineServiceConfig.FSE_TFS_PERSONAL_TOKEN, + CollectionUrl = MachineServiceConfig.TFS_COLLECTION_URL, + PersonalToken = MachineServiceConfig.TFS_PERSONAL_TOKEN, UserEmail = MachineServiceConfig.FSE_TFS_USER_EMAIL }; } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs index f781dbb89..431d64200 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs @@ -18,8 +18,8 @@ namespace Tango.MachineService public static bool USE_DB_ACCESS_TOKENS => bool.Parse(ConfigurationManager.AppSettings[nameof(USE_DB_ACCESS_TOKENS)].ToString()); public static String CDN_ENDPOINT => ConfigurationManager.AppSettings[nameof(CDN_ENDPOINT)].ToString(); - public static String FSE_TFS_COLLECTION_URL => ConfigurationManager.AppSettings[nameof(FSE_TFS_COLLECTION_URL)].ToString(); - public static String FSE_TFS_PERSONAL_TOKEN => ConfigurationManager.AppSettings[nameof(FSE_TFS_PERSONAL_TOKEN)].ToString(); + public static String TFS_COLLECTION_URL => ConfigurationManager.AppSettings[nameof(TFS_COLLECTION_URL)].ToString(); + public static String TFS_PERSONAL_TOKEN => ConfigurationManager.AppSettings[nameof(TFS_PERSONAL_TOKEN)].ToString(); public static String FSE_TFS_USER_EMAIL => ConfigurationManager.AppSettings[nameof(FSE_TFS_USER_EMAIL)].ToString(); } }
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config index 2c6408e50..291145d36 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config +++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config @@ -32,8 +32,8 @@ <add key="USE_DB_ACCESS_TOKENS" value="false" /> <add key="CDN_ENDPOINT" value="https://tango.azureedge.net" /> - <add key="FSE_TFS_COLLECTION_URL" value="https://twinetfs.visualstudio.com" /> - <add key="FSE_TFS_PERSONAL_TOKEN" value="szzfokrceo4rhd4eqi5qpmxn3pa5iwl3q7tlqd36l2m7smz2ynoa" /> + <add key="TFS_COLLECTION_URL" value="https://twinetfs.visualstudio.com" /> + <add key="TFS_PERSONAL_TOKEN" value="pyulwgs7m3v7pizz3oxusypdkdfw43txggo5mjwu2ouyv2qwprhq" /> <add key="FSE_TFS_USER_EMAIL" value="fse@twine-s.com" /> </appSettings> <!-- |
