Zobrazují se příspěvky se štítkem.NET and VS2005. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkem.NET and VS2005. Zobrazit všechny příspěvky

středa 19. října 2016

.NET and Windows proxy problems

Windows has two HTTP APIs, which are unfortunatelly not 100% compatible in case of proxy settings:
  • WinINet, used by Internet Explorer and most of the Windows C/C++ applications. Window proxy settings dialog sets the proxy for the WinINet
  • WinHTTP used by .NET.
So, when you develop a .NET application, is may happen that on a certain computer the Internet Explorer and other apps are connecting well, while your .NET app cannot connect to the Internet.
Since some proxy settings are hidden to the user by the "Automatically detect settings"checkbox, I have made a simple program WinProxyViewer, which may be run with a inexperienced user and the result sent to the application authors.

Default Credentials


.NET does not pick up the proxy credentials entered in the Windows proxy settings, e.g. see this StackOverflow thread. One solution is to add to the application config:

<system .net="">
  <defaultproxy usedefaultcredentials="true" />
</system>
But I preffer the solution in the code (at least for the desktop apps):
try
{
    System.Net.IWebProxy proxy = System.Net.WebRequest.DefaultWebProxy;
    PropertyInfo propInfo = proxy.GetType().GetProperty("WebProxy", BindingFlags.NonPublic | BindingFlags.Instance);
    ((System.Net.WebProxy)propInfo.GetValue(proxy)).UseDefaultCredentials = true;
}
catch (Exception ex)
{
    // log the exception
}


More proxies


The automatic proxy script for the WinINet may contain more proxy servers. The WinINet chooses next cycle the list until it finds the first proxy working. While the .NET (WinHTTP) use the first proxy from the list always, event when it does not work. So the .NET app may be disconnected, while the Internet Explorer is working. There is not known remedy for that. Fortunately, such situations are very rare.

NTLM proxy


.NET (WinHTTP) cannot automatically detect NTLM proxy and use Window credentials for it like the WinINet. There is not known remedy for that. NTLM proxies are sometimes used in the enterpise environments.

Summary


.NET app cannot be 100% compatible with all the Windows proxy settings. A possible solution for that is to have own proxy settings in the app. But the app may be used by people who cannot (security or have no knowledge) to set the proxy settings in the .NET app. So they may be situations, when .NET stays disconnected.

úterý 26. srpna 2008

.NET Zobrazní chyby v DataGridView

Při události CellValidating u DataGridView (DGV) je možné uživatele informovat o chybě několika způsoby.
  1. Klasicky, dialogovým okénkem MessageBox.Show(...).
  2. Nastavit chybu řádky dgv.Rows[e.RowIndex].ErrorText = "Chyba" (pozor, pak se tato chyba musí mazat při EndEdit()).
  3. Nastavit chybu buňky dgv.Rows[e.ColumnIndex, e.RowIndex].ErrorText = "Chyba". Ale chybový obrázek se neobjeví, pokud se buňka edituje. Workaround pro toto je třeba v DataGridView FAQ.
  4. Zobrazit ToolTip.
Bod 1. je asi nejjednodušší, ale ne moc uživatelsky přívětivý, protože se dialogové okénko s chybou musí odsouhlasit, aby zmizelo. Body 2. a 3. jsou často uváděné v příkladech nebo internetových diskusích. Sice se zobrazí pěkná červená blikající ikonka, ale uživatel na ní musí najet myší, aby se dověděl, co je špatně. Proto mi připadá nejlepší bod 4. - zobrazení ToolTipu. Uživatel hned vidí, jakou chybu způsobil a může ji ihned napravit. Navíc je to i poměrně jednoduché.


//deklarace
private ToolTip toolTip = new ToolTip();

...

// incializace, treba v konstruktoru
this.toolTip.ToolTipIcon = ToolTipIcon.Error;
this.toolTip.ToolTipTitle = Properties.Resources.TitleError;
this.dataGridView.CellEndEdit += new DataGridViewCellEventHandler(dataGridView_CellEndEdit);
this.dataGridView.CellValidating +=new DataGridViewCellValidatingEventHandler(dataGridView_CellValidating);

...

// Schovej tool tip po dokonceni editace.
void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (this.toolTip.Active)
{
this.toolTip.Hide(this);
}
}

private void dataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
...
if (error)
{
this.CellValidatingError(e, "Nastala chyba XYZ.");
return;
}
...
}

// Zobraz tooltip, pipni, nastav e.Cancel na true.
public void CellValidatingError(DataGridViewCellValidatingEventArgs e, string msg)
{
e.Cancel = true;
// tooltip
Rectangle cellBounds = this.dataGridView.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
Point location = new Point(cellBounds.Left + this.dataGridView.Location.X, cellBounds.Bottom + this.dataGridView.Location.Y);
this.toolTip.Show(msg, this, location, 3000);
// beep
System.Media.SystemSounds.Beep.Play();
}


Poznámka: při ToolTip.Hide() a ToolTip.Show() se nastaví na prvek Control, ve kterém je DataGridView vložené, v tomto příkladě je to this.

pondělí 11. srpna 2008

.NET C# Souborové operace s progress barem

K mému nemilému překvapení chybí v .NET operace pro kopírování/přesouvání souborů, ke kterým by šel pohodlně připojit nějaký progress bar s informací pro uživatele, jak dalece operace pokročila. Kopírování souborů lze udělat ručně, nebo se dají najít články o použití CopyFileEx z kernel32.dll v C#. Ovšem pro přesun souborů jsem nic rozumného nenašel. Přesun souboru se totiž někdy realizuje jako přejmenování, jindy jako kopírování a vymazání. To může trvat různě dlouho. Nakonec mne překvapil poměrně čerstvý (asi měsíc starý) článek na MSDN: http://msdn.microsoft.com/en-us/library/cc165446.aspx. Ten radí použít v C# třídu FileSystem z VisualBasicu (sic). Tato třída poskytuje při souborových operacích standartní windowsovská dialogová okna, což je pro mé účely postačující. Navíc si i nechá potvrdit přepsání nebo smazání souboru, umí i operovat s celými adresáři. Jestliže ale někdo potřebuje vlastní progress bar nebo jiný způsob informace o postupu souborové operace, tak má asi smůlu.

Poznámka: Pro zobrazní dialogů je potřeba u metod třídy FileSystem použít parametr Microsoft.VisualBasic.FileIO.UIOption.AllDialogs

středa 6. srpna 2008

.NET DataGridView a změna chování při stisku kláves

Na Internetu je posáno mnoho řešení, jak změnit chování DataGridView (DGV) při stisku kláves, např. při Enter přejít na další sloupec místo na další řádku. Bohužel, DGV a ani dokumentace k němu není v tomto ohledu přímočaré, a proto i mnoho lidí (dokonce i z Microsoftu) radí používat EditingControlShowing událost a hlídat KeyDown u objevivšího TextBoxu. To je ovšem takové lámání přes koleno. Nejlepší řešení je od Marka Rideouta, manažera DataGridView v Microsoftu. (Ano, DataGridView má asi svého ředitele :-)), viz http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=88530&SiteID=1

V podstatě stačí vyvtvořit podtřídu DGV a přepsat virtuální funkce:

protected override bool ProcessDialogKey(Keys keyData)
{
Keys keyCode = (keyData & Keys.KeyCode);
if (keyCode == Keys.Enter || keyCode == Keys.Tab)
{
return this.ProcessRightKey(keyData);
}
return base.ProcessDialogKey(keyData);
}

protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
{
return this.ProcessRightKey(e.KeyData);
}
return base.ProcessDataGridViewKey(e);
}

středa 16. července 2008

.NET OnSizeChanged & OnResize

Narazil jsem na stejný problém jako Alan Kleymeyer (a řada dalších). Kterou událost mám použít, OnSizeChanged, nebo OnResize? Alan píše:
"From a user's point of view, they're the same thing. OnResize will be called whenever OnSizeChanged is called. The reason we have both is that OnSizeChanged is used for databinding and we had OnResize first. The user can override either one and see the same behavior."
Haló, programátoři Microsoftu, což takhle jednu z nich označit "obsolete", jab bývá zvykem ve staré dobré Javě? Nebo ti aspoň zmínit v MSDN dokumentaci? Postupně začínám trávit více času s Googlem, než s MSDN nápovědou (F1), když hledám východiska ze spletitostí .NET.

.NET: Nepořádek v pořadí argumentů

Občas používám výjimky ArgumentException nebo ArgumentNullException (a pár dalších, které se váží k chybám argumentů metod). Tyto výjimky umožňují v konstruktoru zadat dva řetězce: název chybného argumentu paramName a chybové hlášení message. Ovšem pořadí těchto arumentů není pokaždé stejné, viz definice:
public ArgumentException (string message, string paramName);
public ArgumentNullException (string paramName, string message);
Že by marketingový tah na propagaci IntelliSense technologie dolňování? V takov0m nepořádku to bez ní opravdu nejde.