|
Hello everybody. For *two weeks*, each day since I installed Windows 7, I have been struggling to get something to work. Something which worked perfectly ok in XP. It's driving me mad, poisoning my life, ruining my days. Why such a simple task works SO CHAOTICALLY!?
I think I discovered a bug in Windows 7, specifically in the way the ShowWindow function works in the standard theme (Aero).
To demonstrate this, I uploaded 2 C# WinForms applications and their source code.
http://www.axonnsd.org/W/P007/BugsDemo.rar
HideableApplication represents an application which you can hide in the SysTray when you close it. Double clicking the SysTray icon reveals it and right clicking will reveal the "Exit" option.
HideableApplicationRevealer attempts to show HideableApplication's window.
The reason I need to accomplish this task is because I minimize my Total Commander and FireFox to the Tray and I want to bring them back via a HotKey. Total Commander offers such a functionality but it is broken.
On Windows XP I managed to accomplish both these tasks without any problems, using the code I attached.
On Windows 7, the behavior is erratic at best, and non-functional at worst.
When HideableApplication runs inside Visual Studio everything works:
- Trying to reveal it via HideableApplicationRevealer from Visual Studio => SUCCESS
- Trying to reveal it via manual execution of HidebleApplicationRevealer.exe from Debug folder => SUCCESS
- Trying to reveal it via running HideableApplicationRevealer.exe via keyboard shortcut => SUCCESS
- Trying to reveal it via running HIdeableApplicationRevealer.exe via a Scheduled Task with Admin Rights => SUCCESS.
When HideableApplication was executed manually (via .exe from Debug folder) AND Visual Studio IS STARTED, it works if I use admin rights or run it manually:
- Trying to reveal it via HideableApplicationRevealer from Visual Studio => FAIL
- Trying to reveal it via manual execution of HidebleApplicationRevealer.exe from Debug folder => SUCCESS
- Trying to reveal it via running HideableApplicationRevealer.exe via keyboard shortcut => FAIL
- Trying to reveal it via running HIdeableApplicationRevealer.exe via a Scheduled Task with Admin Rights => SUCCESS.
- Trying to reveal it via running HideableApplicationRevealer.exe via keyboard shortcut (start menu) which has been given ADMIN RIGHTS => SUCCESS.
When HideableApplication was executed manually (via .exe from Debug folder) AND Visual Studio HAS BEEN SHUT DOWN: it only works if I run it manually (double click exe):
- Trying to reveal it via manual execution of HidebleApplicationRevealer.exe from Debug folder => SUCCESS
- Trying to reveal it via running HideableApplicationRevealer.exe via keyboard shortcut => FAIL
- Trying to reveal it via running HIdeableApplicationRevealer.exe via a Scheduled Task with Admin Rights => PROBLEMS: Window blinks on the TaskBar instead of being shown!
- Trying to reveal it via running HideableApplicationRevealer.exe via keyboard shortcut (start menu) which has been given ADMIN RIGHTS => SUCCESS.
If it matters, I reproduced this behavior both with the Taskbar in its standard position AND also with it set to AutoHide, in the left of the screen.
Apparently, I need admin rights to show a window, but even like this, it doesn't work right when I use the Scheduled Task workaround (create Scheduled Task with admin rights and invoke the Scheduled Task via system32/schtasks.exe /run /tn "task name"). What happens is that AFTER VISUAL STUDIO IS SHUT DOWN, the window blinks on the TaskBar instead of being shown (and has no focus). It does appear, but it has no keyboard focus, which should NOT happen because I also used the SetForegroundWindow API.
This is exactly what happens when I try to run reveal Total Commander as well: read below, same behavior: blinks on taskbar instead of being shown.
And don't even get me started on the difference in behaviors between when running it from Visual Studio and when running it from its usual C:\MyProjects folder.
My TotalCommanderRevealer and FireFoxRevealer exhibit even stranger behaviors: when starting Visual Studio, the Total Commander app stops working properly. Even if I load NO PROJECT, instead of showing TC to me, it just blinks it on the TaskBar. However if I open the TCRevealer project, it starts working again! If I shut down Visual Studio, it STOPS working UNTIL I RESTART WINDOWS.
The FireFoxRevealer instead of revealing FireFox, does something very strange: it shows a small label in the top-left corner of the screen, usually with something related to the opened tab. I suspect this has to do with the Window Style and the way the ShowWindow function works in Windows 7. However, sometimes it works, showing the actual window. But most of the time it doesn't. And when it stops working, I never get it to work again until certain unknown circumstances occur and it works again. Regardless, this worked pefectly under Windows XP and does not work at all now.
If you wish to reproduce the FireFox issue, use the code I attached: instead of searching for "Hideable Application" text in FindWindow API, search for "MozillaWindowClass", install FireFox 7 or 8 and install the FireFox "Minimize To Tray Revived" addon.
I should also mention that I'm aware of the "ForegroundLockTimeout" registry setting and I have set it to 0 everywhere it appears in the Registry. On Windows XP it is set by default to 0 but in Windows 7 the default value was 200000, which I have changed. Maybe somehow it lingers somewhere??? And Visual Studio, while running, sets it to 200000 when I shut it down, until I restart the computer? I looked in the Registry and it doesn't change, it's still 0. But who knows?
|
|
|
|
|
I am sending image path(as image save in folder) from web service like
[System.Web.Services.WebMethod(), System.Web.Script.Services.ScriptMethodAttribute()]
public static string GetDynamicContent(string contextKey)
{
string constr = "Data Source=Subhasish-PC;Initial Catalog=testabhijit;Integrated Security=SSPI;";
string query = "SELECT ImagePath FROM imagetable WHERE id = " + contextKey;
SqlDataAdapter da = new SqlDataAdapter(query, constr);
DataTable table = new DataTable();
da.Fill(table);
string x = table.Rows[0]["ImagePath"].ToString();
return x.ToString();
}
Now at .aspx page i am taking panel and image control, like below
<asp:Panel runat="server" CssClass="modalPopup" ID="panSaving" Style="display: none">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td>
<asp:Image ID="imgClose" runat="server" ImageUrl='' Height="336" Width="430"/>
</td>
</tr>
</table>
</asp:Panel>
My problem is how i will bind ImageUrl of image control......so that which path is sending at web service i can access. Thank you.
|
|
|
|
|
Let us assume a client-server application. The server communicates with a database, which contains a table with users. That table stores the passwords.
Of course, passwords are not stored in clear text. In version 1, MD5 was used.
With version 2, that was changed to SHA-1.
Now a customer with more than a hundred users wants to update from version 1 to version 2.
And suddenly you see a problem: You cannot migrate the passwords because there is no function for calculating the SHA-1 value for a given MD5 value - you need the passwords in clear text which is not available.
How would you handle/avoid such a situation?
|
|
|
|
|
In the new password file, put a header on each record to indicate the hash used, for example
MD5.Fred Smith.qwertukljndfvoijer4tgp[oidjfbvdfv
MD5.Joe Bloggs.lkjrfsgbdqkdfvlkdfv456cxvfth
SHA1Alan Black.345908udfvdf340fgkldrsdfsdfsgb
This allows for graceful migration as passwords are renewed/reissued/whatever.
No claims for originality, but I know this technique works.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Gets my five - the only sensible way to handle it.
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
+5 - To expand on this appraoch, whenever a user logs in successfully you can migrate them silently so that the record is updated to use the new hash, as this is the only time your code would get to see the unhashed value. (I know that you all know this, but it may help someone somewhere to spell it out)
|
|
|
|
|
A good idea, IF you have access to the plaintext credentials. Having such access might create all sorts of security holes, however.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Thanks a lot for your valuable ideas.
The situation is not exactly as described in the scenario above, rather version 2 is available since some time, and now the first customer complained about "lost" passwords - the update script resets them to empty strings.
We do not have a "forgot password" feature which would allow us to generate new passwords and mail them to the users - could be a useful improvement.
I suggested to fix it in a way very similar to your suggestion (an extra column in the user table indicating the method used), and automatically update to the new method as suggested by Reiss.
Thanks also to Luc - his idea could be useful in a future change of password handling.
|
|
|
|
|
If you don't want to do a piecewise migration, which I agree with the above is the best approach, you have to do a mass password reset, using the email for 'forgot password' for all the users.
|
|
|
|
|
if you don't want a gradual migration, do want the better security of SHA-1, and don't mind the extra cost of calculating MD5, then you could store SHA1(MD5(password)) , i.e.:
- for existing passwords perform a one-time conversion: MD5(existing_password) to SHA1(MD5(existing_password)) ;
- for new passwords: store SHA1(MD5(new_password))
|
|
|
|
|
+5 for lateral thinking!
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Thanks a lot for this nice idea.
Hash algorithms are actually optimized for performance, hence the extra cost of chaining the hash functions is in the lines of code only. Indeed I read an article somewhere (can't remember the source) where a low performing hash algorithm was suggested: for a user it doesn't matter if the hash can be calculated in a millionth of a second or in a tenth of a second - for someone trying a brute force attack it does.
|
|
|
|
|
Hi Guys and ladies. I am reading a record into a windows form which works fine. The record structure is: Header details of 463 chars and then a repetative set of records of 276 chars each. Problem is that the string can have anything between 1 and a max of 50 repetative records. On clicking the next button i am trying to display the details from the second record etc. I am trying to figure out how to best acieve this as if I click the button the first time it reads the second block of data fine, if I click it again it reads the second block again instead of reading the third bloack of data.
How do I read the data to be able to get to the third record? Would it be best to load the blocks into a dataset and then maybe read that? Below is the code I currently have.
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Dispose();
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
filepath = txtFileName.Text;
StreamReader sr = new StreamReader(filepath);
string holdLine = sr.ReadLine();
int recLength = holdLine.Length;
int startIndex = 463;
int oneRecLength = 276;
int totalRecs = (recLength - startIndex) / oneRecLength;
int startread = 739;
int lastread = 0;
if ((recLength - 463) > 1015)
{
if((totalRecs - 1) != 0)
{
string nextrec = holdLine.Substring(startread, 276);
HOM_CO_ID = nextrec.Substring(0, 5);
HOM_PROD_CODE = nextrec.Substring(5, 3);
HOM_ACCT_TYPE = nextrec.Substring(8, 1);
HOM_BRANCH = nextrec.Substring(9, 6);
HOM_ACCOUNT_NO = nextrec.Substring(15, 23);
HOM_BUDGET_NO = nextrec.Substring(38, 5);
HOM_ACCOUNT_NAME = nextrec.Substring(43, 30);
HOM_AMOUNT = nextrec.Substring(73, 17);
HOM_REF = nextrec.Substring(90, 20);
HOM_DESCR = nextrec.Substring(110, 47);
HOM_TRAN_CODE = nextrec.Substring(157, 5);
HOM_REVERSAL_DESCR = nextrec.Substring(162, 47);
NOM_REF2 = nextrec.Substring(209, 20);
NOM_DESCRIPTION = nextrec.Substring(229, 47);
txtHomCompId.Text = HOM_CO_ID;
txtHomProdCode.Text = HOM_PROD_CODE;
txtHomAccountType.Text = HOM_ACCT_TYPE;
txtHomBranch.Text = HOM_BRANCH;
txtHomAccNo.Text = HOM_ACCOUNT_NO;
txtHomBudgetNo.Text = HOM_BUDGET_NO;
txtHomAccName.Text = HOM_ACCOUNT_NAME;
txtHomAmount.Text = HOM_AMOUNT;
txtHomRef.Text = HOM_REF;
txtHomDescr.Text = HOM_DESCR;
txtHomTranCode.Text = HOM_TRAN_CODE;
txtHomRevDescr.Text = HOM_REVERSAL_DESCR;
txtNomRef2.Text = NOM_REF2;
txtNomDescr2.Text = NOM_DESCRIPTION;
validateMessage();
totalRecs--;
startread = lastread + 276;
}
}
Excellence is doing ordinary things extraordinarily well.
|
|
|
|
|
I'd create two class members (class variables) of type
- List<String> records
- int recordIndex
In the button2_Click I'd test to see if records collection is null;
If null I'd read the text from file and add each record as a string to the records collection.
I'd then reference the string in the records collection at the recordIndex. Extract the values from the string, set the text control values and increment to recordIndex by one.
You might want to dispose of that Streamreader as well, once finished.
sr.Dispose();
"You get that on the big jobs."
|
|
|
|
|
Well, it seems to me that this line
int startIndex = 463;
is where the problem lies. You should make startIndex a class level variable, then when you finished reading a record you increment this by 276. Personally, I would create a separate class that holds a complete transaction, and then read the file only once, populating a List of such transactions as I went along. Then you can just navigate through the list, backwards and forwards as you wish.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
If it's only 50 records you should parse and read the entire file into a List<Record>, where a Record is a data holding class which is populated in a similar way to your code here, at the start. Working with a proper domain object with properties is much better than working with a string format the whole time.
To read all the records you do something like
List<Record> GetRecords(string s){
List<Record> r = new List<Record>();
ReadHeader(s.Substring(0, HEADER_LENGTH));
s = s.Substring(HEADER_LENGTH);
while(s.Length > 0){
string recordstr = s.Substring(0, RECORD_LENGTH);
s = s.Substring(RECORD_LENGTH);
Record rec = new Record();
rec.CO_ID = recordstr.Substring(0, 5);
r.Add(rec);
}
return r;
}
ed: HEADER_LENGTH = 463 and RECORD_LENGTH = 276.
|
|
|
|
|
I'm trying to have a timer countdown and once it reaches 0 it would move a value from one gridview to another. The build crashes once it reaches 0 and says something about not being able to change controls on different threads. I did some research and they say I need to Invoke? or create a BackgroundWorker?
System.Threading.Timer timer;
int time = 30;
timer = new System.Threading.Timer(new TimerCallback(timerCallback),
null, 0, 1000);
public void timerCallback(Object obj)
{
else
{
timer = 0;
moveToGrid(grid1, grid2);
}
}
The moveToGrid method works fine if I put it in an onClick event but the build crashes when put as shown above. Can anyone point me in the right direction?
|
|
|
|
|
You are going to have to check if invoke is required in the moveToGrid method, something like this:-
void MoveToGrid(DataGridView grid1, DataGridView grid2)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(() => MoveToGrid(grid1, grid2)));
}
else
{
}
}
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
That worked great! Thanks a bunch. At first I didn't think it was going to work because the way I have it set up. Just had to check if invoke was required on two separate methods and worked like a charm.
|
|
|
|
|
Glad to help.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
You may want to read this article[^] on GUI Controls and threads.
The easiest approach could be using the right timer: Windows.Forms.Timer s tick on the GUI thread...
|
|
|
|
|
Yes, for this sort of purely UI related thing I recommend using the Windows.Forms.Timer. It is less accurate, but on a level that you don't care about, and its events go through the normal UI thread message queue.
|
|
|
|
|
I'll have to look into this then. Still learning so anything new is good.
|
|
|
|
|
The timer is being executed on a separate thread, no you didn't create one, it was done for you by the Timer object, but the UI can only be updated from the main thread. You need the Invoke to call the main UI thread and update the grids, as Wayne responded.
No comment
|
|
|
|
|
Respected Sir,
Sir tell me the Way that How I can Create Classic Menu in C# desktop apll. Which fell like flash, & application become attractive - Devdatta
|
|
|
|
|