WPF C# - Standard (non - privilege) user not able to accss the webclient? - c#

Here is the code I am using to check the internet connection. But it always fails. This runs fine with my admin user but not working for standard (non-privilege) user I made. What could be missing here..
if (!App.IsInternetConnected)
{
await Task.Factory.StartNew(() =>
{
App.IsInternetConnected = Utils.IsInternetConnected();
});
}
if (!App.IsInternetConnected)
{
App.ShowMessage("FeatureNotAvailable");
LoginProgress.Visibility = System.Windows.Visibility.Hidden;
return;
}
IsInternetConnected method is as below.
internal static bool IsInternetConnected()
{
try
{
WebClient webclient = new WebClientPool().GetIdleWebClientObject();
try
{
webclient.DownloadString("http://www.google.com");
return true;
}
}
catch (Exception)
{
return false;
}
}
GetIdleWebClientObject is as below.
[MethodImpl(MethodImplOptions.Synchronized)]
public WebClient GetIdleWebClientObject()
{
foreach (WebClient item in WebClientItems)
{
if (!item.IsBusy )
{
Log.Instance.WriteLine("reused webclient");
item.Headers.Clear();
return item;
}
}
Log.Instance.WriteLine("new webclient");
WebClient NewItem = new WebClient();
NewItem.UseDefaultCredentials = true;
//NewItem.Credentials = CredentialCache.DefaultNetworkCredentials;
NewItem.Proxy = WebRequest.GetSystemWebProxy();
WebClientItems.Add(NewItem);
return NewItem;
}

My issue was bit out of way but may help anyone.
It was in line this Log.Instance.WriteLine("new webclient"); This line was creating and writing log file in C:\ drive. Which was not allowed to standard user and throwing exception.
which lead me to show no internet error which was not actually related.

Related

How can I download (from URL) an apk with a button in xamarin Android?

I used WebClient to download a file in my apk. But I got this error:
Unhandled Exception:
System.Net.WebException: An exception occurred during a WebClient request.
And this is the code that I tried:
{
using (WebClient client = new WebClient())
{
client.DownloadFile(
"https://code.org/images/social-media/code-2018-creativity.png",
#"j:\storage\emulated\legacy\Download\code-2018-creativity.png");
}
}
Since you are only referring to a WebException, it may have to do with one of these cases:
The URI formed by combining BaseAddress and address is invalid.
The file or destination folder does not exist. Make sure your path to
the destination folder already exists and that you have permissions to access it.
An error occurred while
downloading data.
If you provide us more information about the exception we may be able to reduce the error to one of these cases. To get the InnerException you can do something like this:
{
using (WebClient client = new WebClient ())
{
try
{
client.DownloadFile (
"https://code.org/images/social-media/code-2018-creativity.png",
#"j:\storage\emulated\legacy\Download\code-2018-creativity.png");
}
catch (Exception ex)
{
while (ex != null)
{
Console.WriteLine (ex.Message);
ex = ex.InnerException;
}
}
}
}
You have to ask permissions on run time even you have mentioned them in your manifest file if you are running Android api level 23 or greater.
Have a look at this blog would help about how to ask a run time permission:requesting-runtime-permissions-in-android
Also, this is the official sample of how to check RuntimePermissions
Refer: xamarin-system-unauthorizedaccessexception-access-to-the-path-is-denied
Update:
To ask run time permissions, you can use this plugin:Plugin.Permissions, install it to your project.
And then, call CheckMyPermissionAsync(); before you download the file:
private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View) sender;
CheckMyPermissionAsync();
}
In the method CheckMyPermissionAsync(), check your Storage permission and then download file:
public async void CheckMyPermissionAsync()
{
var permissionsStartList = new List<Permission>()
{
Permission.Storage
};
var permissionsNeededList = new List<Permission>();
try
{
foreach (var permission in permissionsStartList)
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
if (status != PermissionStatus.Granted)
{
permissionsNeededList.Add(permission);
}
}
}
catch (Exception ex)
{
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(permissionsNeededList.ToArray());
//Check the persimmison again
var storeagePermission = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (storeagePermission == PermissionStatus.Granted)
{
//Download file here
DownloadFile("http://www.dada-data.net/uploads/image/hausmann_abcd.jpg", "XF_Downloads");
}
else {
Console.WriteLine("No permissions");
}
}
You can check the result in the completed event:
private void Completed(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
Console.WriteLine("success");
}
else
{
if (OnFileDownloaded != null) { }
Console.WriteLine("fail");
}
}
Note: pay attention to your filePath,make sure your path is correct, I use:
string pathToNewFolder = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath, folder);
I updated my sample here: runtime-permission-xamarin.android

How to use HttpListener in Identifying the hostheader usage

I a trying to find a hostheader is already under usage. So I start a HTTP listener with an url. I expected an exception, as the url having host header is already registered. The code is below. The URL abc:81 is already up and running, however the listener starts and stops without exception. can anyone help
bool notUnderUse;
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://abc:81/") ;
try
{
listener.Start();
listener.Stop();
notUnderUse = true;
}
catch (Exception ex)
{
notUnderUse = false;
}
I coded the below function with various references and it worked fine.
public static bool IsHostHeaderUnderUse(string ipAddress,string port, string hostname)
{
bool alreadyUnderUse = false;
var header = string.Format("{0}:{1}:{2}", ipAddress, port, hostname);
int? iisVersion = IISUtility.GetIISVersion();
if (iisVersion.HasValue && iisVersion < 7)
{
DirectoryEntry iis = new DirectoryEntry("IIS://localhost/W3SVC");
foreach (DirectoryEntry directoryEntry in iis.Children)
{
var bindings = directoryEntry.Properties["ServerBindings"];
if (bindings.Contains(header))
{
alreadyUnderUse = true;
break;
}
}
}
else
{
var serverManager = new ServerManager();
foreach (Site site in serverManager.Sites)
{
foreach (var binding in site.Bindings)
{
if (binding.BindingInformation.Contains(header))
{
alreadyUnderUse = true;
break;
}
}
if (alreadyUnderUse) { break; }
}
}
return alreadyUnderUse;
}

How to check the Internet connection with .NET, C#, and WPF

I am using .NET, C# and WPF, and I need to check whether the connection is opened to a certain URL, and I can't get any code to work that I have found on the Internet.
I tried:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IAsyncResult result = socket.BeginConnect("localhost/myfolder/", 80, null, null);
bool success = result.AsyncWaitHandle.WaitOne(3000, true);
if (!success)
{
MessageBox.Show("Web Service is down!");
}
else
MessageBox.Show("Everything seems ok");
}
finally
{
socket.Close();
}
But I always get the message that everything is OK even if I shut down my local Apache server.
I also tried:
ing ping = new Ping();
PingReply reply;
try
{
reply = ping.Send("localhost/myfolder/");
if (reply.Status != IPStatus.Success)
MessageBox.Show("The Internet connection is down!");
else
MessageBox.Show("Seems OK");
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
But this always gives an exception (ping seems to work only pinging the server, so localhost works but localhost/myfolder/ doesnt)
Please how to check the connection so it would work for me?
Many developers are solving that "problem" just by ping-ing Google.com. Well...? :/ That will work in most (99%) cases, but how professional is to rely work of Your application on some external web service?
Instead of pinging Google.com, there is an very interesting Windows API function called InternetGetConnectedState(), that recognizes whether You have access to Internet or not.
THE SOLUTION for this situation is:
using System;
using System.Runtime;
using System.Runtime.InteropServices;
 
public class InternetAvailability
{
    [DllImport("wininet.dll")]
    private extern static bool InternetGetConnectedState(out int description, int reservedValue);
 
    public static bool IsInternetAvailable( )
    {
        int description;
        return InternetGetConnectedState(out description, 0);
    }
}
In the end I used my own code:
private bool CheckConnection(String URL)
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Timeout = 5000;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
return true;
else
return false;
}
catch
{
return false;
}
}
An interesting thing is that when the server is down (I turn off my Apache) I'm not getting any HTTP status, but an exception is thrown. But this works good enough :)
Use this:
private bool CheckConnection()
{
WebClient client = new WebClient();
try
{
using (client.OpenRead("http://www.google.com"))
{
}
return true;
}
catch (WebException)
{
return false;
}
}
You can try this;
private bool CheckNet()
{
bool stats;
if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() == true)
{
stats = true;
}
else
{
stats = false;
}
return stats;
}
I went through all the solutions. NetworkInterface.GetIsNetworkAvailable() doesn't check internet connection. It only check whether any network connection is available.
Ping is not reliable as in many network ping is turned off. Connecting to google with webclient is also not 100% reliable and it also has performance overhead if you use it too frequently.
Using Windows NLM API seems a better solution to me.
using NETWORKLIST;
namespace Network.Helpers
{
public class InternetConnectionChecker
{
private readonly INetworkListManager _networkListManager;
public InternetConnectionChecker()
{
_networkListManager = new NetworkListManager();
}
public bool IsConnected()
{
return _networkListManager.IsConnectedToInternet;
}
}
}
This is how to add it to project.
I think this will be more accurate when it comes windows applications, Windows form or WPF apps, Instead of using WebClient or HttpWebRequest,
public class InternetChecker
{
[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
//Creating a function that uses the API function...
public static bool IsConnectedToInternet()
{
int Desc;
return InternetGetConnectedState(out Desc, 0);
}
}
While calling write
if(InternetCheckerCustom.CheckNet())
{
// Do Work
}
else
{
// Show Error MeassgeBox
}
Here is a solution similar to Mahbubur Rahman, but using the COM interface directly an without the need to have a reference to Network List Manager 1.0 Type Library :
dynamic networkListManager = Activator.CreateInstance(
Type.GetTypeFromCLSID(new Guid("{DCB00C01-570F-4A9B-8D69-199FDBA5723B}")));
bool isConnected = networkListManager.IsConnectedToInternet;
Can we use ping just asking?
try
{
System.Net.NetworkInformation.Ping ping = new Ping();
//If you use DNS name as below it will give random time outs
//PingReply result = ping.Send("www.google.com");
//INSTEAD USE IP ADDRESS LIKE BELOW IT WILL GIVE ACCURATE TIMEOUTS
PingReply result = ping.Send("8.8.8.8");
if (result.Status == IPStatus.Success)
return true;
return false;
}
catch
{
return false;
}

webrequest.begingetresponse is taking too much time when the url is invalid

I am using webrequest to fetch some image data. The url may be invaild sometime. In case of invalid URL, begingetresponse is taking time equals to timeout period. Also the control become unresponsive during that period. In other word the async callback is not working asynchronously. Is this expected behaviour?
try
{
// Async requests
WebRequest request = WebRequest.Create(uri);
request.Timeout = RequestTimeOut;
RequestObject requestObject = new RequestObject();
requestObject.Request = request;
request.BeginGetResponse(this.ProcessImage, requestObject);
}
catch (Exception)
{
ShowErrorMessage(uri);
}
private void ProcessImage(IAsyncResult asyncResult)
{
try
{
RequestObject requestObject = (RequestObject)asyncResult.AsyncState;
WebRequest request = requestObject.Request;
WebResponse response = request.EndGetResponse(asyncResult);
Bitmap tile = new Bitmap(response.GetResponseStream());
// do something
}
catch (Exception)
{
ShowErrorMessage();
}
}
looks like this is an issue with .NET. BeginGetResponse blocks until DNS is resolved. In case of wrong URL (like http://somecrap) it tries until it gets timeout. See the following links -
link1 and link2
I just ran into this same situation. While it's not a perfect workaround I decided to use the Ping.SendAsync() to ping the site first. Good part is the async part return immediately. Bad part is the extra step AND not all sites respond to Ping requests.
public void Start(WatchArgs args)
{
var p = new System.Net.NetworkInformation.Ping();
args.State = p;
var po = new System.Net.NetworkInformation.PingOptions(10, true);
p.PingCompleted += new PingCompletedEventHandler(PingResponseReceived);
p.SendAsync(args.Machine.Name, 5 * 1000, Encoding.ASCII.GetBytes("watchdog"), po, args);
}
private void PingResponseReceived(object sender, .PingCompletedEventArgs e)
{
WatchArgs args = e.UserState as WatchArgs;
var p = args.State as System.Net.NetworkInformation.Ping;
p.PingCompleted -= new System.Net.NetworkInformation.PingCompletedEventHandler(HttpSmokeWatcher.PingResponseReceived);
args.State = null;
if (System.Net.NetworkInformation.IPStatus.Success == e.Reply.Status)
{
// ... BeginGetResponse now
}
else
{
/// ... machine not available
}
}
Just code and running for a day but initial result look promising.

C# Keeping Pipes Open

I've Got two Programs (Server / Client)
I'm trying to setup IPC for them (They both run on the same box)
Using System.IO.Pipes & Net 3.5
When I call ComOpen, it opens the Pipe correctly, sends the Process ID to the server, but then the Pipe closes and I get an error when it tries to send "Second Write Test"
So Question is.
How do I keep the Pipe open for the Life of the Program?
(I use the Process ID on the server to close everything down if the Client crashes)
private static StreamWriter MyWriter;
private static StreamReader MyReader;
private static NamedPipeClientStream IPCPipe = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut);
public static bool MyWrite(string DataOut)
{
bool ValidPipeOut = false;
if(ValidComPort)
try
{
// Send Data
using (QstWriter = new StreamWriter(IPCPipe))
{
QstWriter.AutoFlush = true;
QstWriter.WriteLine(QstDataOut);
QstWriter.Close();
QstWriter.Dispose();
}
ValidPipeOut = true;
}
catch
{
ValidPipeOut = false;
}
return ValidPipeOut;
}
public static bool ComOpen()
{
ValidComPort = true;
try { IPCPipe.Connect(1000); }
catch (Exception ex)
{
string Erroris;
Erroris = ex.Message;
if (Erroris == "Already in a connected state.")
{
// We're Already Connected, Ignore this error.
ValidComPort = true;
}
else
{
ValidComPort = false;
MessageBox.Show(Erroris);
}
}
if (ValidComPort)
{
string ClientProcessID = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
MyReader = new StreamReader(IPCPipe);
ValidComPort = MyWrite(ClientProcessID);
ValidComPort = MyWrite("Second Write Test");
}
return ValidComPort;
}
The problem is the following line:
using (QstWriter = new StreamWriter(IPCPipe))
At the end of the using statement, the StreamWriter will be disposed and that will in turn dispose the IPCPipe. You are also explicitly calling Dispose and Close on QstWriter, which will close the pipe too.
To fix this, remove the using statement and the calls to Dispose and Close on QstWriter. And assign+initialize QstWriter only once.

Categories