April, 2008

  • Never doubt thy debugger

    When Vista denies you access to “your” files…

    • 0 Comments

    For my work I have two desktops and a laptop I always bring with me, and  despite all the online synchronization tools out there (SkyDrive, FolderShare, Groove, Mesh etc…) I’m used to SyncToy to keep my important files and folders updated across the three machines; The same is true for my backup .pst files: the laptop is my main machine, I usually make my changes and archives there and then copy the pst on the other two machines.

    But since Vista (and now also with Windows 2008) when I copy the new file and then try to load the data file in Outlook, I always get an access denied error:

    access denied

    Clearly a permission issue and running Outlook with elevated privileges resolves the problem; but explicitly granting Full Control to my account (by the way, I’m member of the Administrators group), taking ownership of the file etc… is not enough, I was still unable to open the file (and I don’t want to run Outlook as Administrator). After many attempts as a last resource I tried to create through Outlook a new empty pst file with the same name of my archive one, and then I overridden it the file I was desperately trying to open and… magic… it worked! smile_omg

    Apparently from the UI everything was fine, so I gave the command line a try; here’s what icacls shows for the the working (pst) and non working (pst.bad) archive folder and files:

    icacls output

    See the difference? smile_baringteeth

     Mandatory Label

    New Integrity Levels and Mandatory Labels in Vista/Win2008

    To make a long story short, the behavior is due to the new Integrity Mechanism first introduced in Vista (see Windows Vista Integrity Level Technical Reference):

    The Windows integrity mechanism is a core component of the Windows security architecture that restricts the access permissions of applications that are running under the same user account and that are less trustworthy.

    The Windows Vista® integrity mechanism extends the security architecture of the operating system by assigning an integrity level to application processes and securable objects.

    Appendix B: icacls and file integrity levels has some more details, and also the article Internet Explorer 7 no longer works after you move the contents of the Temporary Internet Files folder to another folder on a Windows Vista-based computer suggests an interesting solution:

    icacls folder_path /setintegritylevel L

    Actually on my machine I set integrity level to “M” (medium instead of low), and now I have my archive back in Outlook! smile_nerd

     

    I wasted a lot of time and bumped my head on the desk because of this problem, hope at least saves some time to others… 

     

     

    Carlo

    Quote of the day:
    Coming home from very lonely places, all of us go a little mad: whether from great personal success, or just an all-night drive, we are the sole survivors of a world no one else has ever seen. - John le Carre
  • Never doubt thy debugger

    Missing ASP.NET Tab in IIS Management Console (the solution)

    • 1 Comments

    Remember this problem? Well, Tom (and Jeremy and Vandana) has a solution smile_nerd

     

     

    Carlo

    Quote of the day:
    There is no abstract art. You must always start with something. Afterward you can remove all traces of reality. - Pablo Picasso
  • Never doubt thy debugger

    Disable recycling in IIS 7? Use AppCmd

    • 3 Comments

    I stumbled on this while trying to repro a remote debug problem for a customer: as you might know from this post from Johan, debugging ASP.NET on IIS7 needs some special care about the application pool recycling policy otherwise if you’ll not be fast enough IIS will kill your process.

    Well, I was doing some tests and wanted to disable the Regular Time Interval value through the IIS Manager (default for this property is 1749 minutes, i.e. 29 hours):

    Application Pool Advanced Settings 

    But if you try to set the value to zero, I’ll get an error message (at least in Windows 2008 RTM).

    Property value error 

    Luckily we can still use AppCmd to change our config store, here it is how:

    appcmd.exe set AppPool <AppPoolNameHere> /recycling.periodicRestart.time:00:00:00

    And if you now go back to the UI you’ll see the change correctly reflected

    Regular Time Interval 

    Of course you can manually change your applicationHost.config file, but handle it with care and be sure you always have a backup first!

    appcmd add backup <BackupNameHere>

    Use the Administration Pack

    It’s still a preview as of now, but it contains some really interesting new features for the IIS Manager. For example you can select the server node within the Connections left panel and under the Management section you’ll now have a new Configuration Editor feature if you don’t want to use AppCmd or edit the xml file directly:

    Configuration Editor 

    appSettings 

    If you select applicationPools and then enter the (Collection) box, you can change the periodicRestart.time value through the new dialog and from here you can set it to zero without error messages! smile_regular

    Application Pool properties 

    By the way, also note the small hint I highlighted: that means you can set intervals to “00:00:00”, “00:01:00”, “00:02:00” etc…, but not “00:01:30” for example; you’ll get the same from AppCmd too:

    AppCmd output 

     

    Carlo

    Quote of the day:
    If someone wants a sheep, then that means that he exists. - Antoine de Saint-Exupery
  • Never doubt thy debugger

    Blog title context (reloaded)

    • 0 Comments

    As my fond readers might remember, I already rambled about the possibility of changing the blog title last year; nothing has really changed since that post, except the fact that every now and then I’ve been playing with the idea but at last I always put it back in a drawer with the promise to go back to it, sooner or later.

    A couple of days ago I by chance found a site with a few quotes from Dr.House. This is a TV series which I didn’t want to see for quite some time because I don’t really like those “first aid” movies (E.R. is another example) and also I guess because I’m always a bit reluctant to “follow the crowd” and didn’t want to find myself watching something just because it is so popular. But then on a sleepy evening, too tired (or should I say lazy?) to go outside and with nothing interesting to watch on TV, I decided to give this “Dr. House thing” a try… and I liked it smile_omg. Maybe it is for his care and acumen concealed as cinism, or the fact that they proceed with some analysis, make assumptions while trying to understand what’s going wrong and test their therapy till the resolution of the case (I see a parallel with what we in CSS do every day, don’t you?), maybe for the subtle psychological implications… but without being an addict I try to not lose my weekly episode now.

    Well, back to the Dr. House quote site, I found a few of them funny and interesting:

    • I don't ask why patients lie. I just assume they all do
    • I've been a doctor for years. Why do I have to keep assuring people I know what I'm doing?
    • Dr. Chase: How would you feel if I interfered in your personal life? Dr. House: I'd hate it. That's why I cleverly have no personal life
    • Patients always want proof. We're not making cars here, we don't give guarantees
    • You could think I'm wrong, but that's no reason to stop thinking?
    • If you can fake sincerity, you can fake pretty much anything
    • There's nothing in this universe that can't be explained. Eventually
    • How come God gets credit whenever something good happens?
    • Make a note: I should never doubt myself

    The list is much longer, but that’s not the point.

    The last quote is the easier one to adapt to a debugging blog like mine, and since I also like Shakespeare and ancient English literature (not that easy at the beginning being a non native English speaker, but very nice once you get into it) here is my choice:

    Never doubt thy debugger

    What do you think? smile_nerd

    Debugger never lies, at most it tells things we cannot understand… but that’s another story (and making it clear is the purpose of this and other blogs, by the way!)

    Carlo

    Quote of the day:
    The secret of eternal youth is arrested development. - Alice Roosevelt Longworth
  • Never doubt thy debugger

    Share Favorites across different users on the same machine

    • 1 Comments

    If you have a dual boot machine like me (I installed Vista and Windows 2008 on one of my desktops in office) and you’re tired of synchronizing your Favorite folders like I was, here’s a quick trick: open the registry editor (as usual be careful!) and set HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Favorites and HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Favorites to the same folder location (for example “c:\favorites”). The former is the one read by Internet Explorer, while the latter is used to show your Favorites under the Start menu.

    Happy bookmarking smile_regular

     

    Carlo

    Quote of the Day:
    Women like silent men. They think they're listening. - Marcel Archard
  • Never doubt thy debugger

    Again on public hotfix download

    • 4 Comments

    I already touched the subject in a couple of previous posts and replying to direct comments and question I got, and to confirm that we’re doing something (hopefully in the right way smile_wink) on this matter I want to highlight this news from Jeff: Migrating hotfixes to MSDN Code Gallery.

    The essence is that Visual Studio, .NET and other technologies hotfixes can be downloaded directly from http://code.msdn.microsoft.com/Project/ProjectDirectory.aspx?ProjectSearchText=hotfix and start a discussion with other people on the matter, hope you’ll find this useful (and keep the feedback coming of course).

     

     

    Carlo

    Quote of the day:
    The reason lightning doesn't strike twice in the same place is that the same place isn't there the second time. - Willie Tyler
  • Never doubt thy debugger

    Impersonation and remote shares

    • 1 Comments

    Let’s say you developed an ASP.NET application the assemblies are hosted on a network share: if you try to get the authenticated user using System.Environment.UserName you’ll get the account configured to access the network share in IIS (Connect As User). Side note: you’re also using Integrated Authentication and impersonate=”true” in web.config.

    Why?

    Well… ASP.NET impersonates the “Connect As” user you specify in IIS console, therefore Context.Identity.Name returns that account. If you need the authenticated user you must rely on the “old” Request.ServerVariables[“LOGON_USER”] as you were used to do in classic ASP.

     

    Carlo

    Quote of the day:
    It is no good to try to stop knowledge from going forward. Ignorance is never better than knowledge. - Enrico Fermi
  • Never doubt thy debugger

    Very slow TreeView in UpdatePanel

    • 9 Comments

    This is what we got couple of weeks ago: an Ajax enabled ASP.NET web application was using a TreeView control within an UpdatePanel to show a complex tree of hierarchical data (the sample we got had more than 2.000 nodes with varying degrees of nesting). The result was that browsing the tree within IE was considerably slower if compared with Firefox, about 4 times (where Firefox took 2 seconds to complete the operation, IE took 8 seconds a and sometimes a bit more).

    With a repro in our hands, a network trace demonstrated that the communication between client and server was working fine (the problem reproduced also on localhost); while having the problem IE was burning a lot of CPU and the relevant thread had a callstack link this:

    kernel32!TlsGetValue+0xb 
    jscript!GcContext::GetGc+0xc
    jscript!NameTbl::FBaseThread+0xb 
    jscript!NameTbl::GetVal+0xe 
    jscript!VAR::InvokeByName+0x10d 
    jscript!VAR::InvokeDispName+0x43 
    jscript!VAR::InvokeByDispID+0xb9 
    jscript!CScriptRuntime::Run+0x167f 
    jscript!ScrFncObj::Call+0x8d 
    jscript!NameTbl::InvokeInternal+0x40 
    jscript!VAR::InvokeByDispID+0xfd 
    jscript!VAR::InvokeByName+0x165 
    jscript!VAR::InvokeDispName+0x43 
    jscript!VAR::InvokeByDispID+0xb9 
    jscript!CScriptRuntime::Run+0x167f 
    jscript!ScrFncObj::Call+0x8d 
    jscript!NameTbl::InvokeInternal+0x40 
    jscript!VAR::InvokeByDispID+0xfd 
    jscript!VAR::InvokeByName+0x165 
    jscript!VAR::InvokeDispName+0x43 
    jscript!VAR::InvokeByDispID+0xb9 
    jscript!CScriptRuntime::Run+0x167f 
    jscript!ScrFncObj::Call+0x8d 
    
    [...]
    
    mshtml!CBase::InvokeEvent+0x1ad 
    mshtml!CBase::FireEvent+0x105 
    mshtml!CXMLHttpRequest::Fire_onreadystatechange+0x5b 
    mshtml!CXMLHttpRequest::CReadyStateSink::Invoke+0x1d 
    [...]

    The code behind that was quite simple:

    protected void onSelectNodeChange(object sender, EventArgs e)
    {
        Session["selectedNode"] = TreeView1.SelectedNode.ValuePath;
        Session["idFirstTree"] = TreeView1.SelectedNode.Value;
    
        UpdatePanel2.Update();
    }

    The problem is that the hole tree is destroyed and recreated at every iteration (Sys$WebForms$PageRequestManager$_destroyTree in MicrosoftAjaxWebForms.js); the method traverses the whole DOM tree, iterates through and releases them. The tree is actually made of a table with many TableRows and TableCells and many of those cells have nested DIVs as for example

    <TD>
        <DIV style="WIDTH: 20px; HEIGHT: 1px"></DIV>
    </TD>
    <TD>
        <DIV style="WIDTH: 20px; HEIGHT: 1px"></DIV>
    </TD>
    <TD>
        <DIV style="WIDTH: 20px; HEIGHT: 1px"></DIV>
    </TD>
    <TD>
        <DIV style="WIDTH: 20px; HEIGHT: 1px"></DIV>
    </TD>
    <TD>
        <A id=ctl00_TreeView1n121 href="javascript:TreeView_ToggleNode(ctl00_TreeView1_Data,121,ctl00_TreeView1n121,' ',ctl00_TreeView1n121Nodes)">
        <IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Expand Note" src="/MyApp/WebResource.axd?d=poTVB8BI5WzFAOGATmVHQ92ltsYfnmkuDjQn4Ufor001&amp;t=633363364222850001">
        </A>
    </TD>
    <TD class="ctl00_TreeView1_2 ctl00_TreeView1_4" onmouseover="TreeView_HoverNode(ctl00_TreeView1_Data, this)" style="WHITE-SPACE: nowrap" onmouseout=TreeView_UnhoverNode(this)>
        <A class="ctl00_TreeView1_0 ctl00_TreeView1_1 ctl00_TreeView1_3" id=ctl00_TreeView1t121 title="Node one \ Subnode one \ Subnode two \ Subnode three \ Leaf" onclick="TreeView_SelectNode(ctl00_TreeView1_Data, this,'ctl00_TreeView1t121');" href="javascript:__doPostBack('ctl00$TreeView1','5\\6\\7\\8\\9')">Select
        </A>
    </TD>

    This is a very CPU intensive operation in the mshtml model, and unfortunately the IE script and HTML engine have some troubles and performance problems in some scenarios… anyway this is not one of them. The point is that destroy and recreate the content of an UpdatePanel is normal (this is how Ajax works), what’s wrong is that the entire tree is destroyed and recreated thousands of times…

    The TreeView control uses some scripts injected by ASP.NET but those are in conflict with the uses used by Ajax for the UpdatePanel and this is what origins the sort of recursion we saw in the dump. From a supportability point of view this is a known issue and one of the reasons because the TreeView control is incompatible and not supported when hosted within an UpdatePanel:

    The following ASP.NET controls are not compatible with partial-page updates, and are therefore not designed to work inside an UpdatePanel control:

    · TreeView control under several conditions. One is when callbacks are enabled that are not part of an asynchronous postback. Another is when you set styles directly as control properties instead of implicitly styling the control by using a reference to CSS styles. Another is when the EnableClientScript property is false (the default is true). Another is if you change the value of the EnableClientScript property between asynchronous postbacks. For more information, see TreeView Web Server Control Overview.

    (from http://msdn2.microsoft.com/en-us/library/bb386454.aspx)

    A TreeView is always completely rendered in HTML and sent to the client. Depending on the ExpandedState, it sets only the parts visible that should to be seen initially and leaves the rest invisible; this is done by setting the display style of the DIVs and other tags which are part of the tree structure.

    • Without the UpdatePanel (i.e. without using Ajax) here’s what happens:
      • When EnableClientScript=”true” then the TreeView client site script expands/collapses the nodes; this is done calling TreeView_ToggleNode(), setting the display stile to block and updating some status values like ExpandedState. This makes the relevant parts of the tree visible without requesting data from the server. A request is sent to the server only when a node is selected; in such a case the whole tree is sent back to the server with the selected node’s style modified accordingly.
      • With EnableClientScript=”false” on every expand/collapse operation the currently visible part of the tree is sent back to the server
    • When using a TreeView inside an UpdatePanel:
      • When EnableClientScript=”true” then the TreeView client side script expands/collapses the nodes like happens in the case without Ajax. When a node is selected then the whole content of the UpdatePanel (which is the whole TreeView server control) is posted back to the server with the selected node’s style modified
      • With EnableClientScript=”false” the server renders only the visible part of the tree and sends it to the client, i.e. the server only send to the client the markup needed to display the visible part of the tree. Every time a node is expanded, and Ajax request is sent to the server to get the portion of the tree to be displayed; this partial tree is what is sent back to the server with an Ajax postback (the already visible tree part plus the newly expanded tree).

    Conclusion

    In this specific scenario we set EnableClientScript=”false” for the TreeView control and let the Ajax scripts deal with the dynamic behaviors, and that is enough as long as you don’t need specific behaviors you get only through the TreeView client-side scripts. Bottom line: test very carefully this scenario since it might work but it’s still not supported (and not tested by Microsoft) therefore something might suddenly go wrong and we would have very limited possibilities to help you effectively…

     

    P.s.
    Thanks to Stefano Pronti and Karl Tietze for sharing this one.

     

    Carlo

    Quote of the day:
    We learn something every day, and lots of times it's that what we learned the day before was wrong. - Bill Vaughan
Page 1 of 1 (8 items)