diff --git a/App.config b/App.config
deleted file mode 100644
index 4bfa005..0000000
--- a/App.config
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/GacLoader.cs b/GacLoader.cs
new file mode 100644
index 0000000..5025dee
--- /dev/null
+++ b/GacLoader.cs
@@ -0,0 +1,66 @@
+using Ivi.Visa.ConflictManager;
+using System;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace IviVisaNetSample
+{
+#if NET5_0_OR_GREATER
+ ///
+ /// Class used to load .NET Framework assemblies located in GAC from .NET 5+
+ /// Requred only for expiremental using VISA.NET library in .NET 5+
+ ///
+ internal static class GacLoader
+ {
+ ///
+ /// Load an assembly from the GAC.
+ ///
+ ///
+ /// Loaded assembly
+ ///
+ public static Assembly Load(AssemblyName assemblyName)
+ {
+ var gacPaths = new[]
+ {
+ $"{Environment.GetFolderPath(Environment.SpecialFolder.Windows)}\\Microsoft.NET\\assembly\\GAC_MSIL\\{assemblyName.Name}",
+ $"{Environment.GetFolderPath(Environment.SpecialFolder.Windows)}\\assembly\\GAC_MSIL\\{assemblyName.Name}",
+ };
+
+ foreach (var folder in gacPaths.Where(f => Directory.Exists(f)))
+ {
+ foreach (var subfolder in Directory.EnumerateDirectories(folder))
+ {
+ if (subfolder.Contains(Convert.ToHexString(assemblyName.GetPublicKeyToken()), StringComparison.OrdinalIgnoreCase)
+ && subfolder.Contains(assemblyName.Version.ToString(), StringComparison.OrdinalIgnoreCase))
+ {
+ var assemblyPath = Path.Combine(subfolder, assemblyName.Name + ".dll");
+ if (File.Exists(assemblyPath))
+ return Assembly.LoadFrom(assemblyPath);
+ }
+ }
+ }
+ throw new FileNotFoundException($"Assembly {assemblyName} not found.");
+ }
+
+ ///
+ /// Preloading installed VISA implementation assemblies for NET 5+
+ ///
+ public static void LoadInstalledVisaAssemblies() {
+ var installedVisas = new ConflictManager().GetInstalledVisas(ApiType.DotNet);
+ foreach (var visaLibrary in installedVisas)
+ {
+ try
+ {
+ var inst = GacLoader.Load(new AssemblyName(visaLibrary.Location.Substring(visaLibrary.Location.IndexOf(",") + 1)));
+ Console.WriteLine($"Loaded assembly \"{visaLibrary.FriendlyName}\".");
+ }
+ catch (Exception exception)
+ {
+ Console.WriteLine($"Failed to load assembly \"{visaLibrary.FriendlyName}\": {exception.Message}");
+ }
+ }
+ }
+ }
+#endif
+}
diff --git a/IviVisaNetSample.csproj b/IviVisaNetSample.csproj
index a0752ff..14ea97f 100644
--- a/IviVisaNetSample.csproj
+++ b/IviVisaNetSample.csproj
@@ -1,58 +1,13 @@
-
-
-
+
+
- Debug
- AnyCPU
- {181CDD33-8577-4F46-AF93-2A02660E51AC}
Exe
- Properties
- IviVisaNetSample
- IviVisaNetSample
- v4.8
- 512
- true
-
+ net48;net5.0;net8.0
+ AnyCPU;x64;x86
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
-
-
-
-
-
-
-
-
-
-
+
-
+
-
-
-
\ No newline at end of file
+
+
diff --git a/Program.cs b/Program.cs
index 5a0c20f..fe4a210 100644
--- a/Program.cs
+++ b/Program.cs
@@ -9,41 +9,46 @@ static class Program
{
static void Main()
{
- // Get a VISA.NET library version.
- Version VisaNetSharedComponentsVersion = typeof(GlobalResourceManager).Assembly.GetName().Version;
- Console.WriteLine("VISA.NET Shared Components version {0}.", VisaNetSharedComponentsVersion);
+ // Get VISA.NET Shared Components version.
+ Version visaNetSharedComponentsVersion = typeof(GlobalResourceManager).Assembly.GetName().Version;
+ Console.WriteLine($"VISA.NET Shared Components version {visaNetSharedComponentsVersion}.");
// Check whether VISA Shared Components is installed before using VISA.NET.
// If access VISA.NET without the visaConfMgr.dll library, an unhandled exception will
// be thrown during termination process due to a bug in the implementation of the
// VISA.NET Shared Components, andthe application will crash.
- FileVersionInfo VisaSharedComponentsInfo;
try
{
// Get an available version of the VISA Shared Components.
- VisaSharedComponentsInfo = FileVersionInfo.GetVersionInfo(Path.Combine(Environment.SystemDirectory, "visaConfMgr.dll"));
- Console.WriteLine("VISA Shared Components version {0} detected.", VisaSharedComponentsInfo.ProductVersion);
+ FileVersionInfo visaSharedComponentsInfo = FileVersionInfo.GetVersionInfo(Path.Combine(Environment.SystemDirectory, "visaConfMgr.dll"));
+ Console.WriteLine($"VISA Shared Components version {visaSharedComponentsInfo.ProductVersion} detected.");
}
catch (FileNotFoundException)
{
- Console.WriteLine("VISA implementation compatible with VISA.NET Shared Components {0} not found. Please install corresponding vendor-specific VISA implementation first.", VisaNetSharedComponentsVersion);
+ Console.WriteLine($"VISA implementation compatible with VISA.NET Shared Components {visaNetSharedComponentsVersion} not found. Please install corresponding vendor-specific VISA implementation first.");
return;
}
+#if NET5_0_OR_GREATER
+ // Preloading installed VISA implementation assemblies for NET 5+
+ GacLoader.LoadInstalledVisaAssemblies();
+#endif
+
try
{
// Connect to the instrument.
- using (IVisaSession res = GlobalResourceManager.Open("TCPIP0::localhost::5025::SOCKET", AccessModes.ExclusiveLock, 2000))
+ var resourceName = "TCPIP::localhost::5025::SOCKET";
+ using (IVisaSession resource = GlobalResourceManager.Open(resourceName, AccessModes.ExclusiveLock, 2000))
{
- if (res is IMessageBasedSession session)
+ if (resource is IMessageBasedSession session)
{
// Ensure termination character is enabled as here in example we use a SOCKET connection.
session.TerminationCharacterEnabled = true;
// Request information about an instrument.
session.FormattedIO.WriteLine("*IDN?");
- string idn = session.FormattedIO.ReadLine();
- Console.WriteLine("Instrument information: {0}", idn);
+ string instrumentInfo = session.FormattedIO.ReadLine();
+ Console.WriteLine($"Instrument information: {instrumentInfo}");
}
else
{
@@ -51,28 +56,27 @@ static void Main()
}
}
}
- catch (Exception ex)
+ catch (Exception exception)
{
- if (ex is TypeInitializationException && ex.InnerException is DllNotFoundException)
+ if (exception is TypeInitializationException && exception.InnerException is DllNotFoundException)
{
// VISA Shared Components is not installed.
- Console.WriteLine("VISA implementation compatible with VISA.NET Shared Components {0} not found. Please install corresponding vendor-specific VISA implementation first.", VisaNetSharedComponentsVersion);
+ Console.WriteLine($"VISA implementation compatible with VISA.NET Shared Components {visaNetSharedComponentsVersion} not found. Please install corresponding vendor-specific VISA implementation first.");
}
- else if (ex is VisaException
- && ex.Message == "No vendor-specific VISA .NET implementation is installed.")
+ else if (exception is VisaException && exception.Message == "No vendor-specific VISA .NET implementation is installed.")
{
// Vendor-specific VISA.NET implementation is not available.
- Console.WriteLine("VISA implementation compatible with VISA.NET Shared Components {0} not found. Please install corresponding vendor-specific VISA implementation first.", VisaNetSharedComponentsVersion);
+ Console.WriteLine($"VISA implementation compatible with VISA.NET Shared Components {visaNetSharedComponentsVersion} not found. Please install corresponding vendor-specific VISA implementation first.");
}
- else if (ex is EntryPointNotFoundException)
+ else if (exception is EntryPointNotFoundException)
{
- // Installed VISA Shared Components is not compatible with VISA.NET Shared Components
- Console.WriteLine("Installed VISA Shared Components version {0} does not support VISA.NET {1}. Please upgrade VISA implementation.", VisaSharedComponentsInfo.ProductVersion, VisaNetSharedComponentsVersion);
+ // Installed VISA Shared Components are not compatible with VISA.NET Shared Components.
+ Console.WriteLine($"Installed VISA Shared Components version {visaNetSharedComponentsVersion} does not support VISA.NET. Please upgrade VISA implementation.");
}
else
{
// Handle remaining errors.
- Console.WriteLine("Exception: {0}", ex.Message);
+ Console.WriteLine($"Exception: {exception.Message}");
}
}
diff --git a/README.md b/README.md
index a316cfe..2d59929 100644
--- a/README.md
+++ b/README.md
@@ -2,27 +2,47 @@
[![Build Status Github](https://github.com/vnau/IviVisaNetSample/actions/workflows/build.yml/badge.svg)](https://github.com/vnau/IviVisaNetSample/actions/workflows/build.yml) [![Build Status AppVeyor](https://ci.appveyor.com/api/projects/status/dag3r35u0sn1sci3?svg=true)](https://ci.appveyor.com/project/vnau/IviVisaNetSample)
-In traditional approach [VISA.NET Shared Components](http://www.ivifoundation.org/shared_components/) distributed only as part of a vendor's installer for its VISA implementation.
-This approach suppose installation of vendor's VISA library implementation on CI server environment even if communication with instruments is not required on this stage.
+In the traditional approach, [VISA.NET Shared Components](http://www.ivifoundation.org/shared_components/) are distributed solely as part of a vendor's installer for its VISA implementation.
+This approach necessitates the installation of the vendor's VISA library implementation on the CI server environment, even if communication with instruments is not required at this stage.
-If developed application assumed to work with various third-party VISA implementations and no VISA libraries were installed it would be nice if it could provide only a part of the functionality or report VISA library necessity.
+If a developed application is intended to work with various third-party VISA implementations, and no VISA libraries are installed, it would be beneficial if it could provide only a part of the functionality or report the necessity of the VISA library.
-This is simple example of application bypassing those limitations using unofficial NuGet VISA.NET Shared Components distribution [Kelary.Ivi.Visa](https://www.nuget.org/packages/Kelary.Ivi.Visa/).
+This is a simple example of an application bypassing those limitations by using the unofficial NuGet VISA.NET Shared Components distribution, [Kelary.Ivi.Visa](https://www.nuget.org/packages/Kelary.Ivi.Visa/).
-### VISA.NET implementations ###
+### Using VISA.NET in .NET 5+ solutions ###
-In most cases, an application built with VISA.NET Shared Components version 5.5 will work with latter implementations of Shared Components.
+.NET Standard, introduced in 2016, marked a pivotal moment in the evolution of the .NET ecosystem.
+Since then, many versions of .NET have emerged, diminishing the relevance of the traditional .NET Framework for new projects.
-Below is a non-exhausting list of vendor-specific VISA implementations with VISA.NET support.
+Despite these advancements, VISA.NET remains tied to .NET Framework 2.0, with no indication from the IVI Foundation of plans to embrace modern technologies.
+
+A notable challenge is VISA.NET's limited integration into projects with contemporary .NET runtimes.
+However, compatibility has improved since .NET Core 2, allowing referencing of .NET Framework assemblies in compatibility mode. This suggests potential usability of the VISA.NET library and .NET Framework implementations within a modern .NET runtime.
+
+Another challenge arises as the modern .NET runtime no longer uses the GAC, which VISA.NET relies on.
+This issue is mitigated by preloading VISA.NET implementations.
+
+In this repository, an **experimental** .NET 8 example application showcases potential VISA.NET usage with various vendors implementations.
+Despite progress, successful execution is not guaranteed, as the .NET runtime may lack support for all .NET Framework APIs.
+Basic functions have been tested with Rohde & Schwarz and Keysight implementations, but some functions may require further testing.
+
+We look forward to the IVI Foundation moving the VISA.NET library from the .NET Framework to the .Net Standard, which will allow VISA.NET to become not only interchangeable, but also cross-platform.
+
+### Existing VISA.NET implementations ###
+
+In most cases, an application built with VISA.NET Shared Components version 5.5 will work with later implementations of Shared Components.
+For .NET 5+ projects, the Shared Components version must match those that the implementation depends on.
+
+Below is a non-exhaustive list of vendor-specific VISA implementations with VISA.NET support.
| Implementation | Size | VISA.NET Shared Components Version |
| --- | ---- | ---- |
| [Rohde & Schwarz VISA 7.2.3 for Windows](https://scdn.rohde-schwarz.com/ur/pws/dl_downloads/dl_application/application_notes/1dc02___rs_v/RS_VISA_Setup_Win_7_2_3.exe)| 63 MB | 7.2 |
-| [NI-VISA 2023 Q4](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html)| 1.41 GB | 7.2 |
+| [NI-VISA 2023 Q4](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html#494653)| 1.41 GB | 7.2 |
| [Rohde & Schwarz VISA 5.12.3 for Windows](https://www.rohde-schwarz.com/us/applications/r-s-visa-application-note_56280-148812.html) | 59 MB | 5.11 |
| [Keysight IO Libraries Suite 2019](https://www.keysight.com/main/software.jspx?id=2175637) | 251 MB | 5.11 |
-| [NI-VISA 20.0](https://www.ni.com/ru-ru/support/downloads/drivers/download.ni-visa.html#346210)| 1.16 GB | 5.11 |
+| [NI-VISA 20.0](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html#346210)| 1.16 GB | 5.11 |
| [Keysight IO Libraries Suite 2018](https://www.keysight.com/main/software.jspx?id=2175637) | 260 MB | 5.8 |
| [Keysight IO Libraries Suite 17.2](https://www.keysight.com/main/software.jspx?id=2784293) | 191 MB | 5.6 |
-| [NI-VISA 15.0,17.5](http://www.ni.com/download/ni-visa-17.5/7220/en/) | 756 MB | 5.6 |
+| [NI-VISA 15.0,17.5](https://www.ni.com/en/support/downloads/drivers/download.ni-visa.html#306106) | 122 MB | 5.6 |
| [Kikusui KI-VISA 5.5](https://www.kikusui.co.jp/en/download/en/?fn=com_kivisa) | 89 MB | 5.5 |