Friday, December 31, 2004

Updated dot net groups

 
A quick note to say I updated the groups archives a bit. Hopefully the changes are welcome.

A test link or two: one and two



Thursday, December 30, 2004

Blog test for <pre> vs <code> tag

 
I put a lot of code snippets into my blogs, so I've been using <pre> a lot, but I was wondering if I should use <code> instead (or in addition to) <pre>. Testing it out

pre
pre
pre


code
code
code


code pre
code pre
code pre


pre code
pre code
pre code


And the envelope please...



Wednesday, December 29, 2004

HtmlEncode data in your ASP.NET DataGrid

 
OK, I didn't know this, but I found out that a DataGrid BoundColumn will not automatically HtmlEncode your data. So if the data contains HTML entities (e.g. "hello this is a <td>") your web page will break. Yes, it's a gotcha if you were expecting otherwise. Heh.

The solution is to make the column a TemplateColumn, and wrap the DataBinder.Eval statement with Server.HtmlEncode. To make a column a TemplateColumn in the design view, open the DataGrid properties, go to the Property Builder, click Columns in the left hand pane, click the column you want in Selected columns, and click "Convert this column into a Template column." If you're in the HTML pane, you can just replace the asp:BoundColumn tag with an asp:TemplateColumn tag, like below.

Before:

<asp:BoundColumn DataField="Field1" SortExpression="Field1" HeaderText="Field1"></asp:BoundColumn>



After:
<asp:TemplateColumn SortExpression="Field1" HeaderText="Field1">
<ItemTemplate>
<asp:Label id=Label2 runat="server" Text='<%# Server.HtmlEncode(DataBinder.Eval(Container, "DataItem.Field1").ToString()) %>'></asp:Label>
</ItemTemplate>
</asp:TemplateColumn>


If you converted the column to a template column in the IDE design view, you still need to switch to HTML view and add the Server.HtmlEncode function to the Label, e.g.

Before:
<asp:Label id=Label2 runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Field1") %>'></asp:Label>


After:
<asp:Label id=Label2 runat="server" Text='<%# Server.HtmlEncode(DataBinder.Eval(Container, "DataItem.Field1").ToString()) %>'></asp:Label>


Note: Blogger doesn't html encode your posts either. :)



Recursively List Virtual Directories in IIS with C# and DirectoryServices

 
You've probably seen a lot of VBScript scripts that manage IIS via ADSI objects, but let's say you want to write something in .NET. Maybe C#? Maybe compiled code, with a UI?

Enter DirectoryServices, a .NET-friendly wrapper for ADSI (Active Directory Services Interface). IIS (along with LDAP and WinNT) is known as an ADSI Provider, meaning it supports the ADSI interface, enabling you to work with files, directories, etc. So your .NET application can use DirectoryServices to create, delete, and enumerate IIS directories and virtual directories, like this:

Your .NET Application <-> DirectoryServices <-> ADSI <-> IIS

Below is a simple code snippet that will list out all virtual directories in an IIS web site. It's different than other scripts I've seen in that it will list virtual directories below the root.

// call the function once to kick it off
WriteVDirs("localhost", 1, "");

// function that recursively walks through IIS dir & vdirs & lists all the virtual directories
public void WriteVDirs(string serverName, int SiteNumber, string path)
{
DirectoryEntry de =
new DirectoryEntry("IIS://" + serverName + "/W3SVC/" +
SiteNumber.ToString() + "/Root" + path);
DirectoryEntries dirs;
try {
dirs = de.Children;
foreach(DirectoryEntry d in dirs) {
if (0 == String.Compare( d.SchemaClassName, "IIsWebDirectory")) {
string fullPath = path + "/" + d.Name;
WriteVDirs(serverName, SiteNumber, fullPath);
}
else if (0 == String.Compare( d.SchemaClassName, "IIsWebVirtualDir")) {
string fullPath = path + "/" + d.Name;
Console.WriteLine(fullPath + ":" + d.Properties["Path"].Value);
WriteVDirs(serverName, SiteNumber, fullPath);
}
}
}
catch (Exception ex) {
Console.WriteLine("ERROR: " + ex.Message);
}
}


By default the code runs under the credentials of the account running the application, but you can specify a different account using the DirectoryEntry.Username & DirectoryEntry.Password properties, e.g.

  DirectoryEntry de = new DirectoryEntry("IIS://localhost/W3SVC/1");
de.Username = "MYDOMAIN/Username";
de.Password = "password";


Lastly, note that in order to use System.DirectoryServices in your C# project, you'll need to deliberately add a reference to the .NET System.DirectoryServices.dll.

You can research the classes more on MSDN.



Monday, December 27, 2004

Reducing the .net WinForms memory footprint

 
WinForms applications sometimes take up a lot of memory for JIT, memory that isn't needed once your application gets going.

You can reduce the amount of memory being used by shrinking the working set. Use the following code at the end of your form's Load and Deactivate events:


int minsize = 500000; // ~500k
int maxsize = 800000; // ~800k
System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
p.MaxWorkingSet = (IntPtr) maxsize;
p.MinWorkingSet = (IntPtr) minsize;


Note that you won't get all the way down to these levels, but it'll help. Also note that this may have a performance impact if your app really does need all this memory, so you may want to play around with the values & using it for some forms or not.

You can get more info on MSDN.





Friday, December 24, 2004

Search and Replace with Perl

 
A quick update to my older blog about using Perl to do a very very fast find & replace on files.

for /R c:\path\ %i in (*.htm *.gif) do @c:\perl\perl.exe -p -i.bak -e "s/old/new/g" %i


Note that the above is for running from Windows command line only, assuming c:\perl\perl.exe is your Perl intepreter (e.g. ActivePerl). It will recursively update all *.htm and *.gif files starting in c:\path, replacing "old" with "new". I do @perl.exe so that the command prompt doesn't print out a line for every file that it finds.

Also, if you're going to put these in a BAT file, you need to double up the % signs for the variables. This version you can put in a BAT file

for /R c:\path\ %%i in (*.htm *.gif) do @c:\perl\perl.exe -p -i.bak -e "s/old/new/g" %%i





Thursday, December 23, 2004

Programatically configure Windows Processor Scheduling for Applications or Background Services

 
Sometimes you might want to programmatically switch processor priority for applications vs services. You can do it via the Control Panel applet (System->Advanced->Performance Tab->Settings->Advanced Tab->Processor Scheduling). Or, do it in the registry by modifying this key:


HKLM\System\CurrentControlSet\Control\PriorityControl\Win32PrioritySeparation


It's a DWORD key. Set it to 38 for applications, or 24 for services. On a new system it may be set to 2, which will act the same way as 38.



Sunday, December 19, 2004

test

  Thursday, December 16, 2004

DevelopmentNow Groups

 
A quick note to say development now has a newsgroup archive. It's still in beta (alpha?) but it should show quick & steady improvement over the next few weeks. I know I've slacked off on the "developer deal of the day", but that's coming too. My primary goal is to continue blogging and writing about ideas to help the developer community, but I figured having more information, as long as it's useful, can't be all that bad.



SourceSafe restoration with ssrestor.exe

 
A few weeks ago I blogged some scripts that allow you to analyze and back up your VSS installation. But I omitted a restoration script. :)


"C:\Program Files\Microsoft Visual Studio\Common\VSS\win32\ssrestor.exe" -yadmin,password "C:\my_backup.ssa" $/my_project


-yadmin,password is the logon information, e.g. logonname "admin" password "password". You should use the correct login info for your VSS installation. If you omit the -y parameter you'll get prompted for login info. C:\my_backup.ssa is the file created when you backed up your sourcesafe database. And $/my_project is the name of a root-level project in VSS. You can also specify $/ to restore all projects, but it won't work if you already have projects in VSS.

You can use the restoration script to restore your VSS database in case of loss, or to migrate it to a different machine entirely. One trick when migrating a VSS installation is to change the srcsafe.ini of the old machine to a one-liner:


#include \\new_vss_server\vss_share\srcsafe.ini


That means that when users try to connect to the old sourcesafe (via the client or tools such as Visual Studio) they'll be silently "redirected" to the new sourcesafe installation. So you won't have to run around & make everyone re-point their tools to the new installation right away. But...you should still eventually update your projects to use the new server, since eventually the old one will go offline (or something). To switch your Visual Studio projects to the new location, look to the VS menu. Go to File->Source Control->Change Source Control. For each project in the menu:
  • click Browse

  • on the VSS login box click Browse. If new_vss_server is missing from the list
    • click browse again

    • navigate to \\new_vss_server\vss_share\srcsafe.ini

    • click open

    • click OK

  • click prod-web1 from the list, click Open

  • click OK

  • click OK on the working folder screen


  • Oh, and I was having some weirdness with blogger....wasn't finding my FTP server. Wacky. :(



    Tuesday, December 14, 2004

    A regular expressions testing and example site

     
    I don't work with regular expressions very often, so I find myself having to brush up on the nuances from time to time. And it gets old writing email validation expressions again and again and again.

    So, it was a delightful surprise to stumble across RegExLib. It contains almost a thousand ready-to-go expressions -- type in a search term & you view all matching expressions, sorted by ranking. It also has a section where you can test regular expressions, either those from the site or your own. So you can plug away until you find just the right expression to use in your code.



    Protecting Email Addresses on Your Web Site

     
    Want to put your email address on your web site? But, do you want spam-spiders grabbing it and sending you porn, viagra, and mortgages? You do?

    Or, perhaps you don't want all that spam, but you need your email address on your site so people can contact you. The solution is to embed some javascript in your HTML: your email address is stored in an encrypted hive, and an obfuscated javascript function decrypts the hive and displays the human-readable email address for the user. So your email address will appear normally in any javascript-enabled browser, yet if spiders try to read it, they get a bunch of gibberish.

    My current fave is Hiveware's Enkoder. Check it out, and stop that spam cold.



    Deleting directories with a space at the end

     
    Somehow a directory on our network got a space at the end of the name. Some crazy script (in desperate need of Trim(), apparently) created it, I think. And, we were unable to view or delete that folder, since a trailing space is an invalid character for a directory.

    If you find yourself in that dilemma, there's an easy solution: your friend RMDIR. e.g. if the directory is "\\myserver\myshare\directorywithaspace ", use

    rmdir "\\myserver\myshare\directorywithaspace "


    You can also wipe out local directories, e.g.

    rmdir "C:\directorywithaspace "





    Saturday, December 11, 2004

    New Version of Robocopy

     
    We've been using robocopy for years to do file copying & replication. It's better than XCOPY & has a ton of options. We've been using the same Windows NT/2000 version, so it was little embarrassing to discover that a new, improved version came out with the Windows 2003 Resource Kit. Heh. Here are some of the features of the new robocopy...might be worth taking a look. The "jobs" & "monitor source" features might especially be helpful if there's a file share you need to replicate, but don't want to write a scheduled task.

    Lastly, the latest version of robocopy will also run on NT/2000. :)

    Robocopy vXP010

    /B : copy files in Backup mode.
    /ZB : use restartable mode; if access denied use Backup mode.

    /COPY:copyflag[s] : what to COPY (default is /COPY:DAT).
    (copyflags : D=Data, A=Attributes, T=Timestamps).
    (S=Security=NTFS ACLs, O=Owner info, U=aUditing info).


    /COPYALL : COPY ALL file info (equivalent to /COPY:DATSOU).
    /NOCOPY : COPY NO file info (useful with /PURGE).
    /FFT : assume FAT File Times (2-second granularity).
    /256 : turn off very long path (> 256 characters) support.

    /MON:n : MONitor source; run again when more than n changes seen.
    /MOT:m : MOnitor source; run again in m minutes Time, if changed.

    /RH:hhmm-hhmm : Run Hours - times when new copies may be started.
    /PF : check run hours on a Per File (not per pass) basis.

    /IPG:n : Inter-Packet Gap (ms), to free bandwidth on slow lines.

    File Selection Options

    /IT : Include Tweaked files.
    /XJ : eXclude Junction points. (normally included by default).
    /MAXLAD:n : MAXimum Last Access Date - exclude files unused since n.
    /MINLAD:n : MINimum Last Access Date - exclude files used since n.
    (If n < 1900 then n = n days, else n = YYYYMMDD date).

    Logging Options
    /TS : include source file Time Stamps in the output.
    /FP : include Full Pathname of files in the output.
    /NS : No Size - don't log file sizes.
    /NC : No Class - don't log file classes.
    /NFL : No File List - don't log file names.
    /NDL : No Directory List - don't log directory names.
    /TEE : output to console window, as well as the log file.
    /NJH : No Job Header.
    /NJS : No Job Summary.

    Job Options
    /JOB:jobname : take parameters from the named JOB file.
    /SAVE:jobname : SAVE parameters to the named job file
    /QUIT : QUIT after processing command line (to view parameters).
    /NOSD : NO Source Directory is specified.
    /NODD : NO Destination Directory is specified.
    /IF : Include the following Files.


    You can download the resource kit for free from Microsoft. You can also buy it from Amazon if for some reason you...had too much money?



    Wednesday, December 08, 2004

    DevelopmentNow -- Developer Deal of the Day

     
    Starting a new feature here on DevelopmentNow: the developer deal of the day! There are a few different "hot deals" web sites I like to frequent, but I usually have to wade through a lot of non-techie stuff (sweaters, tvs) in order to get to the things that I need for my development work -- hardware, software, & the occasional techie essential item (e.g. a good pair of headphones).

    So here at DevelopmentNow you'll be able to get a more focused list to save you time and money on the stuff you care most about. Let's start it off with two good ones:


    Viking USB00256L2 256 MB USB 2.0 Portable Mini Flash Memory Device -- $15 AR

    God knows what my dad paid for this last xmas, but I've used it faithfully ever since. Fast, small, translucent. If you don't already have a thumb drive, stop living in a world of shame and pick this thing up. It's only $15, after all.


    Corian Pixo C700 17" LCD Monitor with Speakers -- $200 AR

    200 bones for a 17" monitor is a sweet deal. I paid $300 like a month ago. Use it for a primary monitor, or go dualie & impress your friends.



    Monday, December 06, 2004

    Funny Quotes?

     
    I've been toying with an office-themed coffee book with quotes, anecdotes, and photographs. I don't have much content, but I wanted to blog out some of my favorite quotes so I could find them again later. So...

  • "Never let a good excuse go to waste."

  • "You can still use a loose cannon to blow things up, but aim it away from anything important."
    Still working on that one, not sure of the wording

  • "There are no stupid questions, only stupid people."
    (especially when responding to people saying "This may be a stupid question, but...")

  • "Thinking is one of the hardest things to do, which is why so few people spend any time doing it."


  • More to come...



    Wednesday, December 01, 2004

    Impersonation in ASP.NET: System.UnauthorizedAccessException, "ASP.NET is not authorized to access the requested resource", and you

     
    Assume your ASP or ASP.NET page needs to access a network share or some other domain resource, but you need to run that page under a different account other than the default anonymous user account. Let's say you want to run it under your domain username. When you try to run an ASP or ASP.NET page under your account initially, you may get an "ASP.NET is not authorized to access the requested resource" error.

    For the solution, you have a few options:

  • You can create a COM object that accesses the resource, put that COM object into a COM+ Server Application, & run that application under your username/password.

  • Or, if you're on Windows 2003, you can create a new Application Pool, run it under your account, then set your virtual directory to use that pool instead of the default pool.

  • Or, for ASP.NET pages, you can use impersonation:

    1. Choose Windows authentication in the web.config file
      <authentication mode="Windows" />

    2. Disable anonymous access in IIS and instead choose Integrated, Basic (not recommended), or Digest.

    3. Add the identity tag to your web config
      <identity impersonate="true" userName="YOURDOMAIN\yourusername" password="yourpassword"/>

    4. Ensure the aspnet_wp process has the "Act as part of the operating system" privilege by assigning that privilege to the ASPNET account.


  • The above steps should get you further along towards accessing network shares, deleting system files, or whatever other nefarious deed you had in mind. :)

    Other References:
    ASP.NET Identity Matrix
    ASP.NET Impersonation




    Archives
    September 2004   October 2004   November 2004   December 2004   January 2005   February 2005   March 2005   April 2005   May 2005  

    This page is powered by Blogger. Isn't yours?