System.Net's Webclient in C# won't connect to server - c#

Is there something I need to do to get System.Net working with Microsoft Visual C# 2008 Express Edition? I can't seem to get any web type controls or classes to work at all.. the below WebClient example always throws the exception "Unable to connect to the remote server".. and consequently I can't get the WebBrowser control to load a page either.
Here is the code (Edited):
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
using (WebClient client = new WebClient()) {
string s = client.DownloadString("http://www.google.com");
this.textBox1.Text = s;
}
}
}
}
This is in a simple form with only a textbox control (with multiline set to true) in it. The exception gets thrown on the DownloadString(...) line. I also tried using WebRequest.. same exception!
EDIT:
I am connected to a Linksys WRT54G Router that connects directly to my cable modem. I am not behind a proxy server, although I did run proxycfg -u and I got:
Updated proxy settings
Current WinHTTP proxy settings under:
HKEY_LOCAL_MACHINE\
SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections\
WinHttpSettings :
Direct access (no proxy server).
I am using Windows XP and not running any kind of firewall. Only AVG at the moment. I'm pretty sure I shouldn't have to forward any ports or anything, but I did try forwarding port 80 to my workstation on my router. Didn't help.

(update - I meant proxycfg, not httpcfg; proxycfg -u will do the import)
First, there is nothing special about "express" here. Second, contoso is a dummy url.
What OS are you on? And do you go through a proxy server? If so, you might need to configure the OS's http stack - proxycfg will do the job on XP, and can be used to import the user's IE settings.
The sample is fine, although it doesn't correctly handle the multiple IDisposable objects - the following is much simpler:
using (WebClient client = new WebClient()) {
string s = client.DownloadString("http://www.google.com");
// do something with s
}

Do you have any firewall software on your PC that might be affecting it? Have you tried with any sites other than Google?

Related

Controlling AIM-TTI Power supply via C#

I’m working with a Aim-TTi CPX400DP power supply and tasked with using it remotely strictly via Visual Studio using C#. I’ve seen a lot of people on here using LabView and other software but nothing with Visual Studio. In addition upon looking up a manual for this power supply I’m also not seeing any syntax that I could use to call for this power supply in C#. Does anyone have an knowledge or support they could lend for this issue?
I’ve tried downloading NiMax and using it to verify the power supply is connected via USB. It’s denoting the Power supply as COM4. However, when I open up the panel in NiMax there’s no other connections or operations to speak of. I have no way of connecting it and sending or receiving data
Firstly I should let you know I work for Aim-TTi so I can assist in using your CPX400DP in Visual Studio with C#.
The USB port on a CPX400DP is implemented as a CDC class virtual COM port and can be treated as a standard COM port by any application software.
Below you find a small console application that I created in C#.
Make sure to add "using System.IO.Ports;" which may require you to install the package of the same name (published by Microsoft) from the NuGet Package Manager in Visual Studio.
I would recommend single stepping through this code and then you can see the responses you get in the rx_message string.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
namespace CPX_Console
{
class Program
{
static SerialPort _serialPort;
static void Main(string[] args)
{
string tx_message;
string rx_message;
_serialPort = new SerialPort();
// configure the serial port to use the sesired COM port
// Note, you dont have to configure the baud rate or any of the other default serialPort settings
_serialPort.PortName = "COM7";
// open the COM port
_serialPort.Open();
// query the CPX identification string
tx_message = "*IDN?";
_serialPort.WriteLine(tx_message);
// get the response
rx_message = _serialPort.ReadLine();
// set channel 1 output to 1.23V
tx_message = "V1 1.23";
_serialPort.WriteLine(tx_message);
// enable channel 1
tx_message = "OP1 1";
_serialPort.WriteLine(tx_message);
// query the measured output voltage on channel 1
tx_message = "V1O?";
_serialPort.WriteLine(tx_message);
// get the response
rx_message = _serialPort.ReadLine();
// close the COM port
_serialPort.Close();
}
}
}

Creating a COM port out of a ttyUSB port in Ubuntu

The Question
I'm having to work with a rather awkward API at the moment which insists on me giving the address of a device, linked via USB port, in the form COM*. However, on the Ubuntu machine on which I'm working, and have to use, if I plug in this device it will automatically be assigned an address in the form /dev/ttyUSB*.
Given that I can't modify the source code of the API - which I would dearly like to do! - what is the least painful way getting the API to talk to said device?
Extra Detail
An example of how to use the API from the manual:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.caen.RFIDLibrary;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CAENRFIDReader MyReader = new CAENRFIDReader();
MyReader.Connect(CAENRFIDPort.CAENRFID_RS232, "COM3");
CAENRFIDLogicalSource MySource = MyReader.GetSource("Source_0");
CAENRFIDTag[] MyTags = MySource.InventoryTag();
if (MyTags.Length > 0)
{
for (int i = 0; i < MyTags.Length; i++)
{
String s = BitConverter.ToString(MyTags[i].GetId());
Console.WriteLine(s);
}
}
Console.WriteLine("Press a key to end the program.");
Console.ReadKey();
MyReader.Disconnect();
}
}
}
The line MyReader.Connect(CAENRFIDPort.CAENRFID_RS232, "COM3"); is where I'm running into problems.
A little later in the manual, it states that the Connect method is to have two parameters:
ConType: The communication link to use for the connection.
Address: Depending on ConType parameter: IP address for TCP/IP communications ("xxx.xxx.xxx.xxx"), COM port for RS232 communications ("COMx"), an index for USB communications (not yet supported).
Bonus Question
The API in question seems to have been written on the assumption that it would be run on a Windows machine. (It's in C#.) The COM* format seems to be favoured - I'm happy to be corrected on this point - by Windows architectures, whereas Ubuntu seems to favour the ttyUSB* format. Assuming that I can funnel the data from my device from a ttyUSB* port to a COM* port, will the API actually be able to find said data? Or will it incorrectly follow the default Windows path?
Given the new information i suspect you can just give the ttyUSB as the parameter, mono will handle the connection correctly. However the same caution for the line endings below still applies. You might also consider making the parameter a command-line parameter thus making your code run on any platform by being able to supply the COM/USB through the command line parameters. I see no other issues using this code. Did you try it yet?
PS: i think your confusion is actually the statement usb id's are not supported yet, i suspect that is because the library relies on a (text-based) serial connection wich are fundamentally different from direct USB connections (wich drivers normally handle) that handle the connection in a more direct way. The ttyUSB ports on linux however DO represent the (UART) serial connections the same way as windows COM-ports, these are not direct USB connections.
Some handy info about the differences: https://rfc1149.net/blog/2013/03/05/what-is-the-difference-between-devttyusbx-and-devttyacmx/
Old answer
I am assuming you run this program on Mono?
Mono expects the path to the port, so COM* will not do. You could try creating a symlink named COM* to the ttyUSB*. Preferrably located in the environment directory. Once you get them linked the program should see no difference. However line endings in the data/program might be different than on windows. If the device expects CRLF and the program uses Environment.NewLine you might get unexpected behaviour too. It might just be easier if you have the permission/rights to edit the assembly with recompilation tools.

How to access an API running on a remote machine via network

I want to connect to an OKUMA Windows based control from external PC (i.e. Other than OKUMA controller) and utilize the OKUMA Open API on that machine. Is it possible? (If yes then How?)
Below is my code which I want to run from my laptop to check machine running mode. I'm getting errors because Okuma.CLDATAPI can't run on my local PC :
using Okuma.CLDATAPI.Enumerations; // Part of the API on the machine
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace OKUMA_TRIAL
{
public partial class Form1 : Form
{
Okuma.CLDATAPI.DataAPI.CMachine objCMachine;
public Form1()
{
InitializeComponent();
objCMachine = new Okuma.CLDATAPI.DataAPI.CMachine();
objCMachine.Init();
}
private ExecutionModeEnum fnGetRunMode()
{
return objCMachine.GetExecutionMode();
}
private void btnRead_Click(object sender, EventArgs e)
{
txtRunMode.Text = fnGetRunMode().ToString();
}
}
}
If this isn't possible, is there another way to communicate with the machine?
Use Windows Communication Foundation to wrap the API.
Due to popular demand, the Open API SDK now includes a WCF client / service example.
OkumaAmerica/Open-API-SDK/Examples/WCF/
It is important to note that we do not feel comfortable releasing code of a publicly available service with API access, so this example is configured for local-host only. Of course it is trivial to change the configuration, but whomever does so needs to accept all responsibility for doing so.
Microsoft has actually done a good job of documenting WCF features, see below.
Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4
Sample Code
Documentation

How do I refresh dns when my host file changes at run time?

My tool actually rewrites the host file based on a few options and those values are used to do things like communicate with one of several databases via dns, but the problem is that in a different area of the tool, I need to use the current value of the host file. Unfortunately, it seems that the values that are present when the app is first run are all that get used.
I've tried flushing dns, but it doesn't seem to have any effect. The methods I've tried are:
Setting timeout
ServicePointManager.DnsRefreshTimeout = 0 this actually broke everything. I wasn't able to communicate with the database at all.
Importing
[DllImport("dnsapi.dll",EntryPoint="DnsFlushResolverCache")]
private static extern UInt32 DnsFlushResolverCache ();
This didn't seem to have any effect.
How do I ensure that my application is using the current values of my host file?
UPDATE: To be clear, I am not reading the host file in order to use it. The IPs get changed, but the app uses the host name when trying connect to the database. e.g.:
127.1.1.14 MyDatabase is in the host file, the app tries to talk to MyDatabase
App changes the host file to read 127.1.1.16 MyDatabase, the app tries to talk to MyDatabase, but it should resolve to .16, but instead it still resolves to .14
This seems to only affect the app which makes me think that it's caching the DNS the first time it resolves it (i.e. the first time it talks to the database) which is why I tried flushing the dns in the ways outlined above, without success. If I open command prompt and ping MyDatabase -4 then I see the correct IP address resolve. I use my app to change the host file's IP address for that host, then ping MyDatabase -4, and it shows the correct updated IP, so like I said, I think it's the app that is caching it.
I whipped up a quick console application and I didn't seem to be able to reproduce the problem you were seeing. As you can see below this requests the IP of google, then I leave an open ReadLine so I can modify the hosts file. Then come back and it reads it into a new variable and for me at least it pulled what was currently in the hosts file at the time. Are you maybe reading the DNS entry into the application prior to updating the hosts file and simply requesting the DNS information from that object rather than generating a new one? screenshot
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
namespace ConsoleApplication9
{
class Program
{
static void Main(string[] args)
{
string hostName = "google.com";
Console.WriteLine(hostName);
string myIP = Dns.GetHostEntry(hostName).AddressList[0].ToString();
Console.WriteLine("My IP Address is: {0}", myIP);
Console.ReadLine();
Console.WriteLine("Updating Host file");
string newIP = Dns.GetHostEntry(hostName).AddressList[0].ToString();
Console.WriteLine("My IP Address is: {0}", newIP);
Console.ReadLine();
}
}
}

Open the Word Application from a button on a web page

I'm developing a proof of concept web application: A web page with a button that opens the Word Application installed on the user's PC.
I'm stuck with a C# project in Visual Studio 2008 Express (Windows XP client, LAMP server). I've followed the Writing an ActiveX Control in .NET tutorial and after some tuning it worked fine. Then I added my button for opening Word.
The problem is that I can reference the Microsoft.Office.Interop.Word from the project, but I'm not able to access it from the web page. The error says "That assembly does not allow partially trusted callers".
I've read a lot about security in .NET, but I'm totally lost now. Disclaimer: I'm into .NET since 4 days ago.
I've tried to work around this issue but I cannot see the light!!
I don't even know if it will ever be possible!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Word = Microsoft.Office.Interop.Word;
using System.IO;
using System.Security.Permissions;
using System.Security;
[assembly: AllowPartiallyTrustedCallers]
namespace OfficeAutomation
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
private void openWord_Click(object sender, EventArgs e)
{
try
{
Word.Application Word_App = null;
Word_App = new Word.Application();
Word_App.Visible = true;
}
catch (Exception exc)
{
MessageBox.Show("Can't open Word application (" + exc.ToString() + ")");
}
}
}
}
Using .Net Framework 4 + XBAP makes this easy: You could use WPF XBAP instead of ActiveX.
And on Project settings window do:
Signing: unckeck all boxes. (this project does not need to be signed),
under Security tab, Just change it to Full Trust.
The user will be prompted one time if he wants to allow the application to Run.
The post How to provide extra trust for an Internet Explorer hosted assembly in the .NET Security Blog sheds light on the issue. It's dated 2003 so things could have changed now... I don't know.
But a commenter asked (2006)
Is it possible to execute the .net
assembly with all the trust permission
without changing anything on the
client side? We previously have been
using a signed ActiveX in a CAB that
was working fine, and try to port it
to C#.
And Shawnfa answered
No, it is not currently possible to
elevate your permissions on the client
side for a control. The closest
option is ClickOnce which will allow
you to prompt and elevate an
application -- although this
application will not be hosed in the
web page.

Categories