finalize autodetection
also add mainfest for win10 compat
This commit is contained in:
parent
1acf5f44df
commit
64653885a0
10 changed files with 190 additions and 231 deletions
|
@ -54,6 +54,9 @@
|
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
|
||||
|
@ -131,6 +134,7 @@
|
|||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
|
@ -157,6 +161,9 @@
|
|||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="lang\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -6,16 +6,15 @@
|
|||
xmlns:local="clr-namespace:EnvyUpdate"
|
||||
xmlns:tb="http://www.hardcodet.net/taskbar"
|
||||
mc:Ignorable="d"
|
||||
Title="EnvyUpdate" Height="170" Width="463" Icon="icon.ico" ResizeMode="CanMinimize" StateChanged="Window_StateChanged" Closing="Window_Closing">
|
||||
Title="EnvyUpdate" Height="132.5" Width="463" Icon="icon.ico" ResizeMode="CanMinimize" StateChanged="Window_StateChanged" Closing="Window_Closing">
|
||||
<Grid Margin="0,0,0,6">
|
||||
<tb:TaskbarIcon IconSource="/icon.ico" ToolTipText="EnvyUpdate" TrayLeftMouseDown="TaskbarIcon_TrayLeftMouseDown" />
|
||||
<TextBlock HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontWeight="Bold" Width="151"><Run Text="Local d"/><Run Text="river "/><Run Text="v"/><Run Text="ersion:"/></TextBlock>
|
||||
<TextBlock x:Name="textblockGPU" HorizontalAlignment="Left" Margin="166,10,0,0" TextWrapping="Wrap" Text="<none>" VerticalAlignment="Top" RenderTransformOrigin="-0.346,0.564"/>
|
||||
<Label x:Name="labelDrag" Content="Drag nvidia.com-cookies.txt here..." Margin="10,98,12,10" HorizontalAlignment="Center" VerticalAlignment="Center" AllowDrop="True" Drop="Grid_Drop" Height="28" Width="435"/>
|
||||
<Button x:Name="buttonHelp" Content="?" HorizontalAlignment="Left" Margin="425,11,0,0" VerticalAlignment="Top" Width="20" Click="buttonHelp_Click"/>
|
||||
<TextBlock HorizontalAlignment="Left" Margin="10,31,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontWeight="Bold" Width="151"><Run Text="Online "/><Run Text="d"/><Run Text="river "/><Run Text="v"/><Run Text="ersion:"/></TextBlock>
|
||||
<TextBlock x:Name="textblockOnline" HorizontalAlignment="Left" Margin="166,31,0,0" TextWrapping="Wrap" Text="<none>" VerticalAlignment="Top" RenderTransformOrigin="-0.346,0.564"/>
|
||||
<CheckBox x:Name="chkPortable" Content="Portable mode" HorizontalAlignment="Left" Margin="10,78,0,0" VerticalAlignment="Top" IsChecked="True" Unchecked="chkPortable_Unchecked" Checked="chkPortable_Checked"/>
|
||||
<CheckBox x:Name="chkInstall" Content="Install?" HorizontalAlignment="Left" Margin="10,78,0,0" VerticalAlignment="Top" IsChecked="False" Unchecked="chkInstall_Unchecked" Checked="chkInstall_Checked"/>
|
||||
<Button x:Name="buttonDL" Content="⟱" HorizontalAlignment="Left" Margin="250,10,0,0" VerticalAlignment="Top" Width="37" FontSize="20" Height="37" Click="buttonDL_Click" Foreground="White" Background="#FF3CDA00" Visibility="Hidden"/>
|
||||
<CheckBox x:Name="chkAutostart" Content="Autostart" HorizontalAlignment="Left" Margin="10,58,0,0" VerticalAlignment="Top" IsEnabled="False" Checked="chkAutostart_Checked" Unchecked="chkAutostart_Unchecked"/>
|
||||
</Grid>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
@ -21,7 +22,7 @@ namespace EnvyUpdate
|
|||
private readonly string exeloc = System.Reflection.Assembly.GetEntryAssembly().Location;
|
||||
private readonly string exepath = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location) + "\\";
|
||||
private readonly string startmenu = Environment.GetFolderPath(Environment.SpecialFolder.StartMenu);
|
||||
private readonly string version = "1.4";
|
||||
private readonly string version = "2.0";
|
||||
private string argument = null;
|
||||
|
||||
public MainWindow()
|
||||
|
@ -47,11 +48,7 @@ namespace EnvyUpdate
|
|||
MessageBox.Show("Application is already running.");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
if (!Directory.Exists(appdata))
|
||||
{
|
||||
Directory.CreateDirectory(appdata);
|
||||
}
|
||||
// Check if application is in Autorun mode and update
|
||||
// Check if application is installed and update
|
||||
if (exepath == appdata)
|
||||
{
|
||||
try
|
||||
|
@ -65,6 +62,10 @@ namespace EnvyUpdate
|
|||
{
|
||||
// Silently fail.
|
||||
}
|
||||
// Also set correct ticks.
|
||||
chkInstall.IsChecked = true;
|
||||
if (File.Exists(startup + "\\EnvyUpdate.lnk"))
|
||||
chkAutostart.IsChecked = true;
|
||||
}
|
||||
if (Util.GetLocDriv() != null)
|
||||
{
|
||||
|
@ -85,19 +86,11 @@ namespace EnvyUpdate
|
|||
}
|
||||
}
|
||||
|
||||
if (File.Exists(appdata + "nvidia-update.txt"))
|
||||
{
|
||||
chkPortable.IsChecked = false;
|
||||
DispatcherTimer Dt = new DispatcherTimer();
|
||||
Dt.Tick += new EventHandler(Dt_Tick);
|
||||
Dt.Interval = new TimeSpan(5, 0, 0);
|
||||
Dt.Start();
|
||||
Load();
|
||||
}
|
||||
if (File.Exists(startup + "\\EnvyUpdate.lnk"))
|
||||
{
|
||||
chkAutostart.IsChecked = true;
|
||||
}
|
||||
DispatcherTimer Dt = new DispatcherTimer();
|
||||
Dt.Tick += new EventHandler(Dt_Tick);
|
||||
Dt.Interval = new TimeSpan(5, 0, 0);
|
||||
Dt.Start();
|
||||
Load();
|
||||
}
|
||||
|
||||
private void Dt_Tick(object sender, EventArgs e)
|
||||
|
@ -112,38 +105,17 @@ namespace EnvyUpdate
|
|||
//System.Diagnostics.Process.Start("https://github.com/fyr77/EnvyUpdate/");
|
||||
}
|
||||
|
||||
private void Grid_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
{
|
||||
try
|
||||
{
|
||||
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
|
||||
Load(files);
|
||||
}
|
||||
catch (WebException)
|
||||
{
|
||||
MessageBox.Show("Network Error. Are you connected to the internet?", "Network Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
FileInfo f = new FileInfo(appdata + "nvidia-update.txt");
|
||||
|
||||
int psid;
|
||||
int pfid;
|
||||
int osid;
|
||||
int langid;
|
||||
//int langid;
|
||||
|
||||
chkPortable.Visibility = Visibility.Hidden;
|
||||
labelDrag.Content = "Drag nvidia.com-cookies.txt here if you have changed your graphics card.";
|
||||
psid = Util.GetData(f.FullName, "ProductSeries");
|
||||
pfid = Util.GetData(f.FullName, "ProductType");
|
||||
osid = Util.GetData(f.FullName, "OperatingSystem");
|
||||
langid = Util.GetData(f.FullName, "Language");
|
||||
gpuURL = "http://www.nvidia.com/Download/processDriver.aspx?psid=" + psid.ToString() + "&pfid=" + pfid.ToString() + "&osid=" + osid.ToString() + "&lid=" + langid.ToString();
|
||||
psid = Util.GetIDs("psid");
|
||||
pfid = Util.GetIDs("pfid");
|
||||
osid = Util.GetIDs("osid");
|
||||
gpuURL = "http://www.nvidia.com/Download/processDriver.aspx?psid=" + psid.ToString() + "&pfid=" + pfid.ToString() + "&osid=" + osid.ToString(); // + "&lid=" + langid.ToString();
|
||||
WebClient c = new WebClient();
|
||||
gpuURL = c.DownloadString(gpuURL);
|
||||
string pContent = c.DownloadString(gpuURL);
|
||||
|
@ -170,50 +142,6 @@ namespace EnvyUpdate
|
|||
}
|
||||
}
|
||||
|
||||
private void Load(string[] files)
|
||||
{
|
||||
FileInfo f = new FileInfo(files[0]);
|
||||
|
||||
int psid;
|
||||
int pfid;
|
||||
int osid;
|
||||
int langid;
|
||||
|
||||
if (chkPortable.IsChecked == false)
|
||||
{
|
||||
File.Copy(f.FullName, appdata + "nvidia-update.txt", true);
|
||||
f = new FileInfo(appdata + "nvidia-update.txt");
|
||||
|
||||
chkPortable.Visibility = Visibility.Hidden;
|
||||
labelDrag.Content = "Drag nvidia.com-cookies.txt here if you have changed your graphics card.";
|
||||
}
|
||||
psid = Util.GetData(f.FullName, "ProductSeries");
|
||||
pfid = Util.GetData(f.FullName, "ProductType");
|
||||
osid = Util.GetData(f.FullName, "OperatingSystem");
|
||||
langid = Util.GetData(f.FullName, "Language");
|
||||
gpuURL = "http://www.nvidia.com/Download/processDriver.aspx?psid=" + psid.ToString() + "&pfid=" + pfid.ToString() + "&rpf=1&osid=" + osid.ToString() + "&lid=" + langid.ToString() + "&ctk=0";
|
||||
string pContent = null;
|
||||
using (WebClient c = new WebClient())
|
||||
{
|
||||
gpuURL = c.DownloadString(gpuURL);
|
||||
pContent = c.DownloadString(gpuURL);
|
||||
}
|
||||
var pattern = @"\d{3}\.\d{2} ";
|
||||
Regex rgx = new Regex(pattern);
|
||||
var matches = rgx.Matches(pContent);
|
||||
onlineDriv = Convert.ToString(matches[0]);
|
||||
onlineDriv = onlineDriv.Remove(onlineDriv.Length - 5);
|
||||
textblockOnline.Text = onlineDriv;
|
||||
|
||||
if (localDriv != onlineDriv)
|
||||
{
|
||||
textblockOnline.Foreground = Brushes.Red;
|
||||
buttonDL.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
textblockOnline.Foreground = Brushes.Green;
|
||||
}
|
||||
|
||||
private void buttonDL_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start(gpuURL);
|
||||
|
@ -232,42 +160,46 @@ namespace EnvyUpdate
|
|||
}
|
||||
}
|
||||
|
||||
private void chkPortable_Unchecked(object sender, RoutedEventArgs e)
|
||||
private void chkInstall_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (chkAutostart != null)
|
||||
{
|
||||
chkAutostart.IsEnabled = true;
|
||||
}
|
||||
if (exepath != appdata)
|
||||
{
|
||||
if (!Directory.Exists(appdata))
|
||||
{
|
||||
Directory.CreateDirectory(appdata);
|
||||
}
|
||||
File.Copy(exeloc, appdata + "EnvyUpdate.exe", true);
|
||||
Util.CreateShortcut("EnvyUpdate", startmenu, appdata + "EnvyUpdate.exe", "Nvidia Updater Application.");
|
||||
}
|
||||
}
|
||||
|
||||
private void chkPortable_Checked(object sender, RoutedEventArgs e)
|
||||
private void chkInstall_Unchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (chkAutostart != null)
|
||||
{
|
||||
chkAutostart.IsEnabled = false;
|
||||
chkAutostart.IsChecked = false;
|
||||
}
|
||||
if (Directory.Exists(appdata))
|
||||
{
|
||||
File.Delete(appdata + "EnvyUpdate.exe");
|
||||
File.Delete(startup + "\\EnvyUpdate.lnk");
|
||||
File.Delete(startmenu + "\\EnvyUpdate.lnk");
|
||||
}
|
||||
}
|
||||
|
||||
private void chkAutostart_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (exepath != appdata)
|
||||
{
|
||||
File.Copy(exeloc, appdata + "EnvyUpdate.exe", true);
|
||||
Util.CreateShortcut("EnvyUpdate", startup, appdata + "EnvyUpdate.exe", "Nvidia Updater Application.");
|
||||
Util.CreateShortcut("EnvyUpdate", startmenu, appdata + "EnvyUpdate.exe", "Nvidia Updater Application.");
|
||||
}
|
||||
else
|
||||
{
|
||||
chkAutostart.IsEnabled = false;
|
||||
}
|
||||
Util.CreateShortcut("EnvyUpdate", startup, appdata + "EnvyUpdate.exe", "Nvidia Updater Application.");
|
||||
}
|
||||
|
||||
private void chkAutostart_Unchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
File.Delete(appdata + "EnvyUpdate.exe");
|
||||
File.Delete(startup + "\\EnvyUpdate.lnk");
|
||||
File.Delete(startmenu + "\\EnvyUpdate.lnk");
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
|
|
|
@ -12,7 +12,7 @@ using System.Windows;
|
|||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("EnvyUpdate")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2020")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
|
|
@ -196,22 +196,38 @@ namespace EnvyUpdate
|
|||
}
|
||||
}
|
||||
XDocument xDoc = XDocument.Parse(xmlcontent);
|
||||
string gpuName = GetGPUName();
|
||||
|
||||
if (IDtype == "pfid")
|
||||
switch (IDtype)
|
||||
{
|
||||
string gpuName = GetGPUName();
|
||||
id = GetValueFromName(xDoc, gpuName);
|
||||
case "psid":
|
||||
id = GetValueFromName(xDoc, gpuName, false);
|
||||
break;
|
||||
case "pfid":
|
||||
id = GetValueFromName(xDoc, gpuName, true);
|
||||
break;
|
||||
case "osid":
|
||||
id = GetOSID();
|
||||
break;
|
||||
case "langid":
|
||||
// Currently unsupported, because Nvidia has a weird way of naming languages in their native OR english version.
|
||||
// https://www.nvidia.com/Download/API/lookupValueSearch.aspx?TypeID=5
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets Value from Nvidias XML docs by searching for the name. Can be used for OS, Lang and GPU.
|
||||
/// This will produce problems when run on Linux. Good thing Linux has nice package managers to take care of driver updating.
|
||||
/// </summary>
|
||||
/// <param name="xDoc"></param>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="psid"></param>
|
||||
/// <returns></returns>
|
||||
private static int GetValueFromName (XDocument xDoc, string query)
|
||||
private static int GetValueFromName (XDocument xDoc, string query, bool psid)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
|
@ -224,12 +240,20 @@ namespace EnvyUpdate
|
|||
{
|
||||
int value1 = 0;
|
||||
int value2 = 0;
|
||||
string cleanResult = null;
|
||||
|
||||
string result = name.Parent.Value;
|
||||
int index = result.IndexOf(sName);
|
||||
string cleanResult = (index < 0)
|
||||
? result
|
||||
: result.Remove(index, sName.Length);
|
||||
if (psid)
|
||||
{
|
||||
cleanResult = name.Parent.FirstAttribute.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
string result = name.Parent.Value;
|
||||
int index = result.IndexOf(sName);
|
||||
cleanResult = (index < 0)
|
||||
? result
|
||||
: result.Remove(index, sName.Length);
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
|
@ -254,6 +278,42 @@ namespace EnvyUpdate
|
|||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns hardcoded values for the supported operating systems.
|
||||
/// </summary>
|
||||
/// <param name="xDoc"></param>
|
||||
/// <returns></returns>
|
||||
private static int GetOSID()
|
||||
{
|
||||
// This is faster than making a whole web request and searching through XML. This application only supports 8 possible IDs, so they are hardcoded.
|
||||
int value = 0;
|
||||
string OS = Environment.OSVersion.Version.Major.ToString() + "." + Environment.OSVersion.Version.Minor.ToString();
|
||||
|
||||
// Here the 32bit values are used. Later, if the OS is 64bit, we'll add 1, since that is how Nvidia does their IDs.
|
||||
switch (OS)
|
||||
{
|
||||
case "10.0":
|
||||
value = 56;
|
||||
break;
|
||||
case "6.1":
|
||||
value = 18;
|
||||
break;
|
||||
case "6.2":
|
||||
value = 27;
|
||||
break;
|
||||
case "6.3":
|
||||
value = 40;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//Simply increment the ID by 1 if OS is 64bit.
|
||||
if (Environment.Is64BitOperatingSystem)
|
||||
value++;
|
||||
|
||||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns GPU name in lower case.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
|
76
EnvyUpdate/app.manifest
Normal file
76
EnvyUpdate/app.manifest
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC Manifest Options
|
||||
If you want to change the Windows User Account Control level replace the
|
||||
requestedExecutionLevel node with one of the following.
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
Specifying requestedExecutionLevel element will disable file and registry virtualization.
|
||||
Remove this element if your application requires this virtualization for backwards
|
||||
compatibility.
|
||||
-->
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
Reference in a new issue