| Rory's profiledotNotedPhotosBlogLists | Help |
|
November 30 Clobbering the %PATH% var with EnvironmentVariableTargetIf you use Environment.GetEnvironmentVariable("Path") to get the Path and later set it via Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine), you will kill your path, since the former retrieves it from the process's environment block, which includes both Machine and User environments (and more sometimes). I did this block-headed thing, and set my path a couple of times, and it grew to be too long and got truncated. Ouch. Developer tools stop working quickly if that happens. Thankfully, the machine environment on a Windows NT kernel based OS is controlled by a key in the System key of the HKLM hive: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment. This means that on a successful boot, the control set is copied over to a second key called ControlSet002. This is how "Last Known Good Configuration" recovery is accomplished - Windows just uses this backup key if you hit F8 and "Last Known Good" at boot. This means my old path should be in HKEY_LOCAL_MACHINE\System\ControlSet002\Control\Session Manager\Environment. Bingo, it was. What a relief. So, don't forget to call your Environment.GetEnvironmentVariable and Environment.SetEnvironmentVariable methods with matching EnvironmentVariableTarget values, unless you have a carefully considered reason. November 28 Getting more than 1000 results from a DirectorySearcher queryOk, this isn't exactly clear. Need to make a note of this so I don't forget it. The DirectorySeacher only returns 1000 results when the defaults are used. This setting actually comes from an AD server, not the .Net stuff, or even the ADSI or LDAP protocol implementation which are under the covers. So, basically, it's as good as hard-coded. ADSI helps out here, and we can take advantage of it, by just setting the DirectorySearcher.PageSize to a number besides 0. I like to set it to the DirectorySearcher.SizeLimit default which is 1000 (actually, it's 0, but this means 1000). This actually makes ADSI make as many paged requests as needed to get the entire result set, not just the first SizeLimit records. The docs aren't terribly clear on this, and I try to make repeated requests to the server until the resulting SearchResultsCollection's Count property is less than the searcher's PageSize property... which doesn't work since ADSI has done this bit for me and now I'm sitting with all the results in the collection. Here's how to get all the users (with a few properties) in the domain [in IronPython]:
November 25 DirectoryInfo and Path rely on ancient technology - the sad story of MAX_PATHNTFS is a very robust and well architected file system. I like it. I've looked at others, like WinFS (not really a core FS, just a layer on NTFS... but good Oddly, this is hardcoded into two places - Win32 and the CRT:
However, help is at hand... From the MSDN docs:
But, try creating a DirectoryInfo prefixed with \\?\ ... you'll throw an exception since it contains an invalid path char (?). Too bad, since people are finally getting the hang of long file names... one more legacy to detract from the shininess of Vista. I've opened a Connect issue... if you run into this, be sure to vote for it. November 20 DynamicMethod in .Net 2.0 is very powerful, but a debugger visualizer is almost needed to take advantageWe're creating a dynamic thunk layer to host .Net managed objects in Sybase's Powerbuilder (both visual and nonvisual objects) and we want a way to mark up our classes with a bit of metadata in the form of Attribute, and then let reflection take over and write the needed Powerbuilder metadata to describe the objects. This works pretty well - reflection is done on a path at design time on the .Net assemblies and the metadata is generated (it isn't dynamic) for Powerbuilder. At runtime, there were few options since it is dynamic - late-binding calls need to be made in this case. But what about all that great .Net metadata...? Couldn't we use that to bring a bit more load (or JIT) time binding into the picture, so that the parameters are mapped out in memory to specific method handle locations? Well, in comes DynamicMethod. It is a dynamically built bit of IL which is then, of course, JITted into machine code... at load time. MS calls it Lightweight Code Generation in case you haven't found this bit already. It's generally an important component of the dynamic language groundswell in the .Net code space. All sorts of fun ideas from dynamic app reconfiguration and optimization to evolutionary algorithms stand out as being able to be easily taken advantage of. Sure you could always do this with System.Reflection.Emit, but it's much easier now, since all the assembly stuff is taken out - methods belong to the current assembly. Debugging one of these dynamic methods is a big pain, though. I went through the trouble of wiring up some debug writelines to get an idea of why my hand crafted IL worked, but the dynamically generated stuff didn't... and ran into an InvalidOperationException trying to access the GetILAsByteArray method. The exception text is very, very misleading: "System.InvalidOperationException : Operation is not valid due to the current state of the object." What this really means is "Not implemented." For shame! The MethodBase base class throws this. This is what NotImplementedException or NotSupportedException are for, I believe. At least give some textual clues which are not misleading. So, on a hunt to find a better method of debugging these dynamic methods, I came upon this debugger visualizer. I was skeptical at first, but I tried it out and found it was very nice! It implements the most easily accessible examples like the MSDN doc's and Joel Pobar's. Do try when you go down this path... it will save you time and headache. However, you will still need to know IL. November 09 MSysInternals keeps the BSOD goingThat MS acquired Sysinternals is old news - but what pleases me is that they are keeping the BSOD screen saver around - they are definitely loosening up as a company. http://www.microsoft.com/technet/sysinternals/Miscellaneous/BlueScreen.mspx November 06 Be safe: rid yourself of MSXML4Last week there was a post which finally helped me emerge from the shrouding mists of confusion on MSXML versions. After reading this, I was finally put at ease about which versions are which, and which to use. Now, apparently, there is a zero-day exploit on MSXML 4. But, according to the well timed post above, we really shouldn't be using MSXML 4. In fact, Adam made it clear that MSXML 6 is the one to use, if you need MSXML 4 functionality:
So, I recommend you kill MSXML 4 from being used on your machine from IE. You can do this with the registry, by setting what is known as the "kill bit". Here's how you do that from the command line (forget the .reg file approach MS outlines in the workaround).
Of course, this will break sites which use MSXML 4 - but they shouldn't be doing so. Kindly write them and ask them to redo this bit, pointing to the above clarification on MSXML. November 03 Getting today's date (without the time) in T-SQL (enhanced)Ok, I thought about it some more.
I have been surprised by all the hits on dotNoted which are looking for ways to express the date without the time in SQL Server's T-SQL.
And I realized how lame the string concatination example looks. So I went back to the drawing board to give you some more T-SQLly goodness. Here's the result. It keeps the datetime binary throughout, so all the overhead converting to and manipulating strings is eliminated. Plus, it seems a bit more elegant:
Let's try to compare the performance of this method to the string method...
DECLARE DECLARE SET DECLARE SELECT DECLARE DECLARE DECLARE SELECT SELECT WHILE BEGIN END
SELECT SELECT @end - @start as "Binary Method Time"SELECT @i = 0SELECT @start = getdate()WHILE (@i < @iterationcount)BEGIN SELECT @tdate = CAST(YEAR(getdate()) as varchar) + RIGHT('00'+CAST(MONTH(getdate()) as varchar), 2) + RIGHT('00'+CAST(DAY(getdate()) as varchar), 2) SELECT @i = @i+1END SELECT @end = getdate()SELECT @end - @start as "String Method Time"Here are the results after iterating 1,000,000 times -
Not very impressive gains, but it probably is worth using the binary method. Not worth converting existing code, however. The succinctness of the binary method is it's strongest point - it can be inlined into the code more easily than the comparitively unwieldy string method, but if your looking for massive performance gains, they aren't here. It is a relatively easy thing for the engine to compute, either way.
November 02 Windows Vista License Terms ShockerWell, I'm shocked, shocked, to learn of this change. Windows had been slated to allow reinstall one time on your hardware. The usual suspects had a field day trashing this. I was pretty bummed myself...
But that changed today:
They apparently heard the feedback, and are changing the license terms.... MS changing the license terms to suit customer wishes? Now I am convinced they are trying to change their evil ways. |
|
|