Visual Studio 2015 has problems communicating using VISA Libraries - c#

I'm having problems with the VISA-Com Libraries to communicate with a Keysight (N6700B) power supply.
I have some C# code I am compiling in Visual Studio 2015, and it does not work. However, if I compile the same code in Visual Studio 2012, then it works.
Basically I am just doing simple communication with the device:
using Ivi.Visa.Interop;
//...
string address = "USB0::2391::2311::MY54002380::0::INSTR";
ResourceManager rm = new ResourceManager();
FormattedIO488 myDmm = (IMessage)rm.Open(address , AccessMode.NO_LOCK, 2000, "");
myDmm.WriteString("*RST"); // reset the device
myDmm.WriteString("*IDN?"); // request the IDN string;
string IDN = myDmm.ReadString(); // This is where it fails, returning: "VI_ERROR_TMO: A timeout occurred"
Also, the power supply has an error state of: "Error -420, Query UNTERMINATED"
The code does not work with VS2015, but it DOES work with VS2012.
(In VS2012 I get no errors at all.)
I have tried downloading the latest drivers from KeySight, and it still does not work (www.keysight.com/find/iosuitedownload).
Does anyone have any idea why it would be breaking with VS2015 but work with VS2012?
I've looked up "Quere Unterminated" and some say that it could be a missing Termination character "\n". I've tried adding the "\n" to both writeStrings, and it still fails.
EDIT: I have also now tried using (in various places):
myDmm.IO.TerminationCharacterEnabled = true; // and = false
myDmm.FlushWrite(); // also tried passing in "true" (default is 'false')
I also tried adding the:
myDmm.IO.TerminationCharacter
to the WriteStrings.

http://download.ni.com/support/softlib//visa/NI-VISA/15.0/Windows/readme.html
Microsoft Visual Studio Support
The following table lists the programming languages and Microsoft Visual Studio versions supported by this version of NI-VISA.
Earlier versions of NI-VISA support other application software and language versions. For more information on Visual Studio compatibility with earlier versions of VISA, refer to ni.com/info and enter the info code NETlegacydrivers. To find and download an earlier version of a driver, refer to ni.com/downloads.
Visual Studio Versions Support by NI-VISA:
Visual C++ MFC1 -------------- 2008
Framework 3.5 Languages (Visual C# and Visual Basic .NET) -- 2008
.NET Framework 4.0 Languages (Visual C# and Visual Basic .NET)-- 2010
.NET Framework 4.5 Languages (Visual C# and Visual Basic .NET)-- 2012
So apparently the drivers don't work with VS2015... (not sure how a newer version doesn't work.. but okay)
EDIT, FOUND ANSWER
Someone from NI-VISTA told me to just add "true" as a second parameter:
myDmm.WriteString("*RST",true); // reset the device
myDmm.WriteString("*IDN?",true); // request the IDN string;
string IDN = myDmm.ReadString(); // now it works.
I'm not sure why "true" wasn't needed in 2012, and why it is needed in 2015... oh well.

I confirm: the method WriteString() (but not only this) needs the bool parameter flushAndEND = true (default value = false) in order to complete the command. Without it, the instrument can't parse the instruction. If you send multiple commands, the instrument can't separate and identify them.
I suggest you to use the Keysight IO monitor for sniffing the communication between your instruments and you controller (PC?) . It's an utility of the IO Libraries Suite (v17.1).
For details, see the attached IFormattedIO488 interface definition, belonging to the reference Ivi.Visa.Interop.
using System.Runtime.InteropServices;
namespace Ivi.Visa.Interop
{
[...]
public interface IFormattedIO488
{
[DispId(1610678274)]
bool InstrumentBigEndian { get; set; }
[DispId(1610678272)]
IMessage IO { get; set; }
void FlushRead();
void FlushWrite(bool sendEND = false);
dynamic ReadIEEEBlock(IEEEBinaryType type, bool seekToBlock = false, bool flushToEND = false);
dynamic ReadList(IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, string listSeperator = ",;");
dynamic ReadNumber(IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, bool flushToEND = false);
string ReadString();
void SetBufferSize(BufferMask mask, int size);
void WriteIEEEBlock(string Command, object data, bool flushAndEND = false);
void WriteList(ref object data, IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, string listSeperator = ",", bool flushAndEND = false);
void WriteNumber(object data, IEEEASCIIType type = IEEEASCIIType.ASCIIType_Any, bool flushAndEND = false);
void WriteString(string data, bool flushAndEND = false);
}
}

Have you tried the ReadBytes method? This method reads a fixed amount of bytes from the device. The error you've encountered most probably occurs because the the visa driver tries to read data until a termination character, which you never explicitly set, is received.
Try setting the TerminationCharacter Property to either \n or \r (depending on the instrument) and it should work. Furthermore, you might want to add it to the commands you send as well so the instrument won't bother you with this error (-420) anymore.

Related

Visual Studio IDE0059 C# Unnecessary assignment of a value bug?

I have the following C# Code (I reduced it to the bare minimum to simplify it). Visual Studio 2019, .NET Framework 4.7.2.
public void Demo()
{
ReportStart();
var success = false;
try
{
int no = 1;
switch (no)
{
case 1:
default:
break;
}
DoSomething();
success = true;
}
finally
{
ReportEnd(success);
}
}
From my understanding, there is nothing wrong about it. The function may fail (I don't want to catch it) but before leaving, it will report successful execution to another method. When debugging, it does exactly what it should.
Interestingly, Visual Studio 2019 will report the following:
When I follow the suggestion by choosing "Remove redundant assignment", it will remove the line success = true;, effectively changing the outcome!
Now what is the switch/case for, you'd ask? When removing it, the recommendation disappears:
Is there any reason for that, or is it a bug in Visual Studio?
It seems to be a known issue with Roslyn and Visual Studio 2019 16.4, please refer to the GitHub issues #39755 and #39344.
The milestone is set to the version 16.5 Preview 2, so it was already fixed and you can try the preview 2 of 16.5 version or wait for stable one (personally, I'm not using a Preview versions)

Access violation exception c#

This is my code that throws an exception, it just randomly started today here is the photo :
Here is the whole page code and the error exception :
public frmWFDocumentDetail()
{
InitializeComponent();
NavigationInTransition navigateInTransition = new NavigationInTransition();
navigateInTransition.Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardIn };
navigateInTransition.Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardIn };
NavigationOutTransition navigateOutTransition = new NavigationOutTransition();
navigateOutTransition.Backward = new TurnstileTransition { Mode = TurnstileTransitionMode.BackwardOut };
navigateOutTransition.Forward = new TurnstileTransition { Mode = TurnstileTransitionMode.ForwardOut };
TransitionService.SetNavigationInTransition(this, navigateInTransition);
TransitionService.SetNavigationOutTransition(this, navigateOutTransition);
DataContext = App.ViewModel_WFDocumentDetailItems;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
//**this is how you pass parameters through to a new page**//
string processID = "-1";
string processName = "";
NavigationContext.QueryString.TryGetValue("processID", out processID);
NavigationContext.QueryString.TryGetValue("processName", out processName);
App.ViewModel_WFDocumentHeaderItems.LoadData("johnny", processID);
App.ViewModel_WFDocumentDetailItems.LoadData("johnny");
}
and the access violation :
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory
is corrupt.
I have read up on it, some people say it is nvidia network manager, and some people say I must set some setting like Suppress JIT optimization , and ignore gpu memory if value isn't changed... but nothing works? Can anyone please please send me in the right direction?
As requested , the full stack
i used the setting taylorjohnl gave me "Debug -> Options and Settings -> Debugging -> General -> Enable Just My Code",and then the error went right to the piece of xaml that was a syntax error, and boom fixed it and app works again :) so violation error for me was basically a reference error, hope this can help other people as well, also use expression blend in silverlight to debug xaml in the UI
I had a similar problem which in the end was resolved by submitting crash dump to MS Tech Support. Here is their response:
The gist is that The crash is a known bug in the version 5.0 of comctl32.dll (Windows Common Controls), which ships with the Windows OS. This bug will not be fixed in version 5.0 of the common controls, because that version was for applications existing prior to Windows XP. It has since been fixed in version 6.0 of comctl32.dll, which is included with Windows XP and later. Note that both versions of comctl32.dll (5.0 and 6.0) are included with every version of Windows since Windows XP. The older one is just there for backwards compatibility purposes for very old applications.
To resolve the problem, you need to change the application to have it opt into version 6.0 of comctl32.dll. Within a Windows Forms application, this is done by calling into the Application.EnableVisualStyles method at startup of the application. If you are developing within a C# project, then you can do this by adding the call prior to your Application.Run call within your application's entry point. For example:
[STAThread]
static void Main()
{
Application.EnableVisualStyles(); //Add this line
Application.Run(new Form1());
}
If you are in a Visual Basic .Net project, you can opt into this by going to your project properties, and then selecting the "Enable Application Framework" and "Enable XP Visual Styles" checkboxes on the Application property page.
Once you do this, it should resolve this particular access violation.
what is code in the InitializeComponent()? there is some class refer to null in it, (mostly is a event handler). once it is trigger, it will report AccessViolation.

Recommended way to test for iOS Version specific feature at runtime

I'm targetting IOS 4.3 and 5.0 with an app built against the 5.0 SDK and would like to add support for the Twitter functionality introduced in iOS5 only when the app runs on a iOS5 device. What is the recommended way to reliably test for the availability of these OS features at runtime without having your app crash?
I know you do this using respondsToSelector in Objective-C but how is it done in C#?
With recent MonoTouch versions you can use the following code:
if (UIDevice.CurrentDevice.CheckSystemVersion (5, 0)) {
window.RootViewController = navigation;
} else {
window.AddSubview (navigation.View);
}
Otherwise you can get a string from UIDevice.CurrentDevice.SystemVersion and do some checks with your own code.
Follow up to comments, including mine...
If you want to check by feature you can do something like:
MonoTouch.Twitter.TWRequest req = new MonoTouch.Twitter.TWRequest ();
if (req.Handle == IntPtr.Zero) {
Console.WriteLine ("No Twitter support before iOS5");
}
What happens is that the selector to create the TWRequest instance will return null and the .NET object will be created in an invalid (unusable) state that you can query with the Handle property. Again YMMV, testing is key :-)

Uninstalling my Office 2010 plugin leaves a null pointer exception

I've been trying to track down why my Office2010 plugin leaves a null pointer exception during uninstall and the 2007 version does not. (Edit: 2007 is at same state as 2010 - FAIL)
To narrow it down I have put in a couple of eventlog traps, meaning if code reaches this point - I should get something in the Eventlog. No such luck. Now either I written the eventlog trap wrong or code doesn't reach that point.
In the CustomSetupActions - ClickOnceInstaller.cs
public void Uninstall(System.Collections.IDictionary savedState)
{
// write something to eventlog
// This is not being fired, the exception doesn't reach here or writing to eventlog fails.
if (!EventLog.SourceExists("OfficePlugin"))
{
EventLog.CreateEventSource("OfficePlugin", "Application");
}
EventLog.WriteEntry
("OfficePlugin"
, string.Format("Uninstalling: (bug hunting)"), EventLogEntryType.Information);
string deploymentLocation = (string)savedState["deploymentLocation"];
if (deploymentLocation != null)
{
string arguments = String.Format(
"/S /U \"{0}\"", deploymentLocation);
ExecuteVSTOInstaller(arguments);
}
}
As for the ExecuteVSTOInstaller(string arguments)
2007 refers to: string subPath = #"Microsoft Shared\VSTO\9.0\VSTOInstaller.exe";
2010 refers to: string subPath = #"Microsoft Shared\VSTO\10.0\VSTOInstaller.exe";
If the first trap had fired, this is where I would have placed the trap afterwards.
--
I have another method that handles the registration db
RegisterOffice2010AddIn.cs
public void UnRegisterAddIn(string applicationName, string addInName)
{
Next line is precisely the same eventlog trap as I just used/shown.
Difference between the two (2007 vs 2010).
private const string UserSettingsLocation =
#"Software\Microsoft\Office\12.0\User Settings";
vs
private const string UserSettingsLocation =
#"Software\Microsoft\Office\14.0\User Settings";
I can't think of any other place that might be interesting to place the trap. I have a CustomInstaller which doesn't do anything besides Dispose(bool disposing) and InitializeComponent()
Development:
Action start 14:21:00: PublishFeatures.
Action ended 14:21:00: PublishFeatures. Return value 1.
Action start 14:21:00: PublishProduct.
Action ended 14:21:00: PublishProduct. Return value 1.
Action start 14:21:00: InstallExecute.
MSI (c) (B8:BC) [14:21:01:013]: Font created. Charset: Req=0, Ret=0, Font: Req=MS Shell Dlg, Ret=MS Shell Dlg
Error 1001. Error 1001. An exception occurred while uninstalling. This exception will be ignored and the uninstall will continue. However, the application might not be fully uninstalled after the uninstall is complete. --> Object reference not set to an instance of an object.
DEBUG: Error 2769: Custom Action _EE8A0D36_BE55_421F_9A55_95470C001D87.uninstall did not close 1 MSIHANDLEs.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2769. The arguments are: _EE8A0D36_BE55_421F_9A55_95470C001D87.uninstall, 1,
Action ended 14:21:05: InstallExecute. Return value 3.
Action ended 14:21:06: INSTALL. Return value 3.
Googling the Error 2769 - gives an answer of "[TARGETDIR]\" , but I dont reference TargetDir, I reference deploymentLocation. And Yes I have tried adding the "\" to places I could think of. Including the setup - Registry - HKLM\Software\MS\Office\12.0\ ...etc... \Addins\Excel/Word/Outlook and the Manifest keyvalue. Gave no feedback, good or bad, errors or otherwise. I'm at a loss what else to try to hunt this one down.
I have a guess it is referencing to this, in the VDPROJ:
{
"Name" = "8:UnregisterOutlookAddIn"
"Condition" = "8:"
"Object" = "8:_73E71A44EB72485AB7367745F7D57F49"
"FileType" = "3:1"
"InstallAction" = "3:4"
"Arguments" = "8:"
"EntryPoint" = "8:"
"Sequence" = "3:3"
"Identifier" = "8:_EE8A0D36_BE55_421F_9A55_95470C001D87"
"InstallerClass" = "11:TRUE"
"CustomActionData" = "8:/addinName=\"OUR.Outlook.Outlook2010AddIn\" /application=\"Outlook\""
}
I found it throws two exception - the secondary under CustomSetupActions and UnregisterAddIn and the primary under ClickOnceInstaller and Uninstall. Howcome I mention them as 2ndary and primary. Well it will do the exception in CustomAction and then the killing one in ClickOnce. I've eliminated the one in CustomActions and I now only have to worry about the ClickOnce. From what I can gather the ClickOnce implements the interface specified in the Setup Project (Install, Rollback, Commit, Uninstall). I only have to figure out how it can run amiss the Uninstall method.
Disclaimer: Unless ofcourse I'm mistaken and is barking up the wrong tree.
Change to WiX. It became a workaround as the original is still true.

Use C# to interact with Windows Update

Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
Add a Reference to WUApiLib to your C# project.
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
From there, you should be able to do some nice things :)
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits).
Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}

Categories

Resources