Thursday, September 1, 2011

Powershell Asynchronous Download String

WebClient DownloadStringAsync
Powershell Register-ObjectEvent
PSEventArgs Properties
# - get webclient
$webClient = new-object net.webclient

# - register event handler for DownloadStringCompleted event
#   action script block is event handler code, show string DownloadStringCompletedEventArgs.Result
register-objectEvent $webClient downloadStringCompleted e1 {write-host $args[1].result}  #positional input params

# - begin asynchronous download string
#   event handlers will execute when download is complete
$webClient.downloadStringAsync("http://www.expressionsoftware.com")

# - list event subscriptions
get-eventSubscriber  #output #SubscriptionId  : 1
                             #SourceObject    : System.Net.WebClient
                             #EventName       : downloadStringCompleted
                             #SourceIdentifier: e1
                             #Action          : System.Management.Automation.PSEventJob
                             #SupportEvent    : False
                             #ForwardEvent    : False
                             #HandlerDelegate :

# - list jobs
get-job | fl  #output  #Id           : 1
                       #Name         : e1
                       #Command      : write-host $args[1].result
                       #State        : Running
                       #JobStateInfo : Running
                       #HasMoreData  : True
                       #Finished     : System.Threading.ManualResetEvent
                       #InstanceId   : 010f31f4-e8d2-4742-a782-79057faefebf
                       #Module       : __DynamicModule_a48149c1-5a56-4172-bc68-473ec7c83119
                       #StatusMessage:   #Location
                       #ChildJobs    : {}  #Output, Error, Progress, Verbose, Debug, Warning

# - register another handler, multiple event handlers supported, named input params
register-objectEvent -inputObject $webClient `
                     -eventName downloadStringCompleted `
                     -sourceIdentifier e2 `
                     -action {write-host ("async event at {0}`nevent handler source identifier: {1}`n{2}" -f ($event.timeGenerated.tostring("HH:mm:ss")), $event.sourceIdentifier, $args[1].result)}

# - unregister events
unregister-event -subscriptionId 1
unregister-event -sourceIdentifier e2
get-eventsubscriber -force | unregister-event -force  #unregister all events

# - synchronous download string
$webClient.downloadString("http://www.expressionsoftware.com")

Powershell asynchronous download file with WebClient DownloadFileAsync

Thursday, August 25, 2011

notes, a blog in a blog

- set browser title date
  function formatDateTime(date) {  //12:34:00
    date = date || new Date();
    return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
  }

  (function() {
    document.title = formatDateTime() + " " + document.title;
  }());  //immediate

- browser scroll
  document.body.scrollTop = 500;  //c
  $(window).scrollTop(500);       //cfi

- json comments
  /**** json ****
  '{
       "id"       : 99,
       "comments" : [ "foo",
                      "bar",
                      "yak yak yak"
                    ],
       "debug"    : { "version" : "1a",
                      "todo"    : [ "hack",
                                    "the",
                                    "code"
                                  ]
       }
  }'
  ****/
  var json = '{ "id" : 99, "comments" : [ "foo", "bar", "yak yak yak" ], "debug" : { "version" : "1a", "todo" : [ "hack", "the", "code" ] }}',
      x = JSON.parse(json);
  
- powershell format file one line, json
  function formatOneLine($infile, $outfile) {
    $x = [io.file]::readAllText($infile)
    $x = ($x -replace "`r`n", "")  #remove line breaks
    $x = ($x -replace " +", " ")   #replace spaces with single
    "len: {0}" -f $x.length
    $x
    $x > $outfile
  }
  #$infile  = "x:\input.txt"
  #$outfile = "x:\output.txt"
  #formatOneLine $infile $outfile

- html offline caching manifest file, mvc
  filename: file.appcache

  CACHE MANIFEST
  #file.appcache v0102_140000
  /js/file.js
  style.css

- mime types
  - html offline caching manifest file: .appcache = text/cache-manifest
  - less.css: .less = text/css

- powershell utf8 getbytes string
  [text.encoding]::utf8.getBytes("foo bar")
  #102, 111, 111, 32, 98, 97, 114

- powershell print ascii characters values
  #0..127
  65..90  | %{"{0}  {1}" -f $_, [char]$_}
  97..122 | %{"{0}  {1}" -f $_, [char]$_}

    65  A   97  a
    66  B   98  b
    67  C   99  c
    68  D  100  d
    69  E  101  e
    70  F  102  f
    71  G  103  g
    72  H  104  h
    73  I  105  i
    74  J  106  j
    75  K  107  k
    76  L  108  l
    77  M  109  m
    78  N  110  n
    79  O  111  o
    80  P  112  p
    81  Q  113  q
    82  R  114  r
    83  S  115  s
    84  T  116  t
    85  U  117  u
    86  V  118  v
    87  W  119  w
    88  X  120  x
    89  Y  121  y
    90  Z  122  z

- powershell byte array
  [byte[]] $bytes = 0, 1, 255
  [byte[]] (0, 1, 255)  #alt

- regex lookbehind non-capturing regex, array, csv, records
  - $data = "^1,2,,foo"

  - match 1st element
    $data -match "(?<=\^)\w*"          | out-null; $matches[0]  #1

  - match 2nd element (n-1)
    $data -match "(?<=\^(\w*,){1})\w*" | out-null; $matches[0]  #2

  - match 3rd element (n-1)
    $data -match "(?<=\^(\w*,){2})\w*" | out-null; $matches[0]  #index 3

  - match 4th element (n-1)
    $data -match "(?<=\^(\w*,){3})\w*" | out-null; $matches[0]  #foo

- powershell build index
  $index = "^"; 1..10 | %{$index += "{0}," -f $_}; $index;
  #^1,2,3,4,5,6,7,8,9,10,

- c# sort dictionary keys orderby
  var d = new Dictionary<string, string> { { "foo", "bar"},
                                           { "a",   "1"  } };
  Debug.WriteLine("key count = " + d.Count);

  foreach (var key in d.Keys.OrderBy(k => k)) {
    Debug.WriteLine(string.Format("{0} = {1}", key, d[key]));  //key = value
  }

  //key count = 2
  //a = 1
  //foo = bar

- powershell sort string characters
  "foobar".toCharArray() | sort | %{write-host $_ -nonewline}; echo "`n"
  #abfoor

- javascript delete all dom elements by type, reverse loop delete
  var x = document.getElementsByTagName("img");
  for(var i=(x.length-1); i>=0; i--) {
    x[i].parentNode.removeChild(x[i]);
  }

  - javascript set image source
    var x = document.getElementsByTagName("img");
    for(var i=0; i<x.length; i++) {
      x[i].src="";
    }

  - all elements
    document.getElementsByTagName("*")

- hex color scale #000000 - ffffff, dark to light
  dark to light  0123456789abcdef 0-9a-f
  light to dark  fedcba9876543210 f-a9-0

- webpage text and background color dom javascript
  - black background #000, ghost text #111
    document.body.style.backgroundColor = "#000"; document.body.style.color = "#111";

  - white background #fff, ghost text #eee
    document.body.style.backgroundColor = "#fff"; document.body.style.color = "#eee";

  - wicked terminal green
    document.body.style.backgroundColor = "#000"; document.body.style.color = "#1ca62e";

  - all elements
    var x = document.getElementsByTagName("*");
    for(var i=0; i<x.length; i++) {
      x[i].style.backgroundColor = "#000";
      x[i].style.color = "#aaa"
    }

- text editor colors font
  https://www.expressionsoftware.com/apps/texteditor/
  var x = document.getElementsByTagName("textarea")[0];
  x.style.backgroundColor = "#000";
  x.style.color = "#444";
  x.style["font-family"] = "verdana"
  x.style.borderColor = "#000";
  x.style.margin = "0";
  x.style.padding = "1em 0 0 2em";

- powershell .net regex matches match collection
  $x = "foo123bar1234"
  $matchCollection = [text.regularExpressions.regex]::matches($x, "\d")
  $matchCollection.count  #7
  $matchCollection | sort -unique | %{$_.value}  #1
                                                 #2
                                                 #3
                                                 #4

- powershell regex string url to alpha numeric
  function alphaNum($string) {
    $string -replace "[^a-zA-Z0-9]", ""
  }

  alphaNum foo@bar1.com
          #foobar1com

  alphaNum expressionsoftware.com/foo/bar.htm?a=1
          #expressionsoftwarecomfoobarhtma1

- powershell regex string url to alpha numeric underscore
  #2 pass replace
  function alphaNumUnderscore($string) {
    ($string -replace "[^a-zA-Z0-9]", "_") -replace "__+", "_"
  }

  alphaNumUnderscore foo@bar1.com
                    #foo_bar1_com

  alphaNumUnderscore expressionsoftware.com/foo/bar.htm?a=1
                     #expressionsoftware_com_foo_bar_htm_a_1

  #webpage url to filename
  function alphaNumUnderscoreToFilename($string) {
    "$(alphaNumUnderscore($string)).txt"
  }

  alphaNumUnderscoreToFilename expressionsoftware.com/foo/bar.htm?a=1
                              #expressionsoftware_com_foo_bar_htm_a_1.txt

- msbuild 4
  $mb = "c:\windows\microsoft.net\framework64\v4.0.30319\msbuild.exe"
  &$mb /help
  &$mb /version /nologo

  $proj = "x:\app.sln"
  &$mb $proj /t:rebuild /p:configuration=debug    /nologo
  &$mb $proj /t:rebuild /p:configuration=release  /nologo

- browser javascript console
  document.cookie
  document.body.innerHTML
  document.body.innerHTML.indexOf("foo")
  "foo bar".indexOf("bar")  #4

- powershell json javascriptSerializer
  add-type -assembly system.web.extensions

  $js = new-object system.web.script.serialization.javascriptSerializer
  $json = '{foo:"bar", "x":100}'
  $data = $js.deserializeObject($json)  #generic string-object dictionary
  $data  #KEY  VALUE
         #foo  bar
         #x    100

  $data.keys  #foo
              #x

  $data["foo"]  #bar

  $hashtable = @{ foo = "bar"; "panic" = $false }
  $hashtable  #NAME   VALUE
              #panic  False
              #foo    bar

  $json = $js.serialize($hashtable)  #{"panic":false,"foo":"bar"}

- bookmarklets tested chrome
  javascript:( alert(123) )();
  javascript:( function(){var d = new Date(); alert(d);} )();
  javascript:( function(){this.document.title = "foo";} )();
  javascript:( function(){var title = prompt("Current page title: " + document.title + "\n\nEnter a page title:", ""); if (title) {document.title = title;}} )();

  javascript:( function(){(document.getElementById("x")).value = "foo bar";} )();;
  javascript:( function(){(document.getElementById("x")).style.backgroundColor = "lime";} )();
  javascript:( function(){(document.getElementsByTagName("x")[0]).style.height = "100px";} )();

- powershell add line numbers to file
  $file = "x:\file.txt"
  $i = 1; gc $file | %{"{0} {1}" -f $i++, $_}             #output to console only
  $i = 1; gc $file | %{"{0} {1}" -f $i++, $_} | sc $file  #overwrite file with set-content (sc)

- powershell get-content (gc) does not get the last empty line in a file
  workaround?

- powershell spell word one letter at a time
  $s = "foo bar"
  1..($s.length) | %{$s.substring(0, $_)}  #f
                                           #fo
                                           #foo
                                           #foo
                                           #foo b
                                           #foo ba
                                           #foo bar

- google chrome incognito shortcut
  c:\users\john\appdata\local\google\chrome\application\chrome.exe --incognito

- chrome://about/
  chrome://downloads/
  chrome://history/
  chrome://plugins/
  chrome://settings/browser
  chrome://settings/personal
  chrome://settings/advanced
  chrome://settings/cookies

- powershell encrypt string
  function encryptString($stringToEncrypt,
                         $encryptionKeyPassword,  #add salt
                         $randomInitializationVector) {

    [expressionSoftware.security.cryptography.rijndaelCrypt]::encryptString($stringToEncrypt, $encryptionKeyPassword, $randomInitializationVector)
  }

  #powershell encrypt string prompt
  function encryptStringPrompt() {
    $stringToEncrypt            = (read-host -prompt "string to encrypt")
    $encryptionKeyPassword      = (read-host -prompt "encryption key password")  #add salt
    $randomInitializationVector = (read-host -prompt "random initialization vector")

    [expressionSoftware.security.cryptography.rijndaelCrypt]::encryptString($stringToEncrypt, $encryptionKeyPassword, $randomInitializationVector)
  }

  #powershell encrypt string prompt secure string
  function encryptStringPromptSecureString() {
    $stringToEncrypt            = (read-host -asSecureString -prompt "string to encrypt")
    $encryptionKeyPassword      = (read-host -asSecureString -prompt "encryption key password")  #add salt
    $randomInitializationVector = (read-host -asSecureString -prompt "random initialization vector")

    [expressionSoftware.security.cryptography.rijndaelCrypt]::encryptString(
      (getValueFromSecureString $stringToEncrypt),
      (getValueFromSecureString $encryptionKeyPassword),
      (getValueFromSecureString $randomInitializationVector))
  }

- powershell decrypt string
  function decryptString($encryptedStringBase64,
                         $encryptionKeyPassword,  #add salt
                         $randomInitializationVector) {

    [expressionSoftware.security.cryptography.rijndaelCrypt]::decryptString($encryptedStringBase64, $encryptionKeyPassword, $randomInitializationVector)
  }

  #powershell decrypt string prompt
  function decryptStringPrompt() {
    $encryptedStringBase64      = (read-host -prompt "encrypted base64 string to decrypt")
    $encryptionKeyPassword      = (read-host -prompt "encryption key password")  #add salt
    $randomInitializationVector = (read-host -prompt "random initialization vector")

    [expressionSoftware.security.cryptography.rijndaelCrypt]::decryptString($encryptedStringBase64, $encryptionKeyPassword, $randomInitializationVector)
  }

  #powershell decrypt string prompt secure string
  function decryptStringPromptSecureString() {
    $encryptedStringBase64      = (read-host -asSecureString -prompt "encrypted base64 string to decrypt")
    $encryptionKeyPassword      = (read-host -asSecureString -prompt "encryption key password")  #add salt
    $randomInitializationVector = (read-host -asSecureString -prompt "random initialization vector")
    [expressionSoftware.security.cryptography.rijndaelCrypt]::decryptString(
      (getValueFromSecureString $encryptedStringBase64),
      (getValueFromSecureString $encryptionKeyPassword),
      (getValueFromSecureString $randomInitializationVector))
  }

- powershell encrypt string example
  - encryptString "foo" "B@R7" "1X#f0"
    WMVK/75wXuK9r4+8l+iPa7jS9sXJBtM7zF6QysJsbVE=

    #powershell encrypt string prompt example
    encryptStringPrompt
    string to encrypt: foo
    encryption key password: B@R7
    random initialization vector: 1X#f0
    WMVK/75wXuK9r4+8l+iPa7jS9sXJBtM7zF6QysJsbVE=

    #powershell encrypt string prompt secure string example
    encryptStringPromptSecureString
    string to encrypt: ***
    encryption key password: ****
    random initialization vector: *****
    WMVK/75wXuK9r4+8l+iPa7jS9sXJBtM7zF6QysJsbVE=

- powershell decrypt string example
  - decryptString "WMVK/75wXuK9r4+8l+iPa7jS9sXJBtM7zF6QysJsbVE=" "B@R7" "1X#f0"
    foo

    #powershell decrypt string prompt example
    decryptStringPrompt
    encrypted base64 string to decrypt: WMVK/75wXuK9r4+8l+iPa7jS9sXJBtM7zF6QysJsbVE=
    encryption key password: B@R7
    random initialization vector: 1X#f0
    foo

    #powershell decrypt string prompt secure string example
    decryptStringPromptSecureString
    encrypted base64 string to decrypt: ********************************************
    encryption key password: ****
    random initialization vector: *****
    foo

- powershell string encryption source code here-string, c#
  $encryptionSourceCode = @"
//****************************************************************
  using System;
  using System.IO;
  using System.Security.Cryptography;
  using System.Text;

  namespace ExpressionSoftware.Security.Cryptography {

      public static class RijndaelCrypt {

          public static string
          EncryptString(string stringToEncrypt,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: string to encrypt, encryption key/password, random initialization vector
              //out: encrypted string in base64 format

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert string to bytes
              var bytesToEncrypt = Encoding.UTF8.GetBytes(stringToEncrypt);

              //encrypt bytes
              var encryptedBytes = Encrypt(bytesToEncrypt, key, iv);

              //convert encrypted bytes to base64 string
              var encryptedStringBase64 = Convert.ToBase64String(encryptedBytes);

              return encryptedStringBase64;
          }

          public static string
          DecryptString(string encryptedStringBase64,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: encrypted string in base64 format, encryption key/password, random initialization vector
              //out: decrypted string

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert encrypted base64 string to bytes
              var encryptedBytes = Convert.FromBase64String(encryptedStringBase64);

              //decrypt bytes
              var decryptedBytes = Decrypt(encryptedBytes, key, iv);

              //convert decrypted bytes to string
              var decryptedString = Encoding.UTF8.GetString(decryptedBytes);

              return decryptedString;
          }

          public static byte[]
          Encrypt(byte[] bytesToEncrypt,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to encrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: encrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform encryptor = rijndael.CreateEncryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(bytesToEncrypt, encryptor);
                  }
              }
          }

          public static byte[]
          Decrypt(byte[] encryptedBytes,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to decrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: decrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform decryptor = rijndael.CreateDecryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(encryptedBytes, decryptor);
                  }
              }
          }

          static byte[]
          CryptData(byte[] data,
                    ICryptoTransform cryptor) {

              var ms = new MemoryStream();
              using (var cryptoStream = new CryptoStream(ms, cryptor, CryptoStreamMode.Write)) {
                  cryptoStream.Write(data, 0, data.Length);
              }
              return ms.ToArray();
          }

      }

      public static class Hash {

          public static byte[]
          HashString(string stringToHash,
                     Type hashType) {

              //in: string to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //convert string to bytes
              byte[] bytes = Encoding.UTF8.GetBytes(stringToHash);

              //hash bytes
              var hashedBytes = HashByteArray(bytes, hashType);

              return hashedBytes;
          }

          public static byte[]
          HashByteArray(byte[] bytesToHash,
                        Type hashType) {

              //in: byte array to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //create hash algorithm
              var hashAlgorithm = HashAlgorithm.Create(hashType.Name);

              //hash bytes
              var hashedBytes = hashAlgorithm.ComputeHash(bytesToHash);

              return hashedBytes;
          }
      }

  }
//****************************************************************
"@

  add-type -typeDefinition $encryptionSourceCode

- powershell get value from secure string
  #alt, use ConvertFrom-SecureString cmdlet
  function getValueFromSecureString($secureString) {
    $marshal = [runtime.interopServices.marshal]
    $ptr = $marshal::secureStringToBSTR($secureString)
    $marshal::ptrToStringBSTR($ptr)  #output
    $marshal::zeroFreeBSTR($ptr)
  }

  $secureString = read-host -asSecureString -prompt "password"
  password: ***  #foo
  getValueFromSecureString $secureString  #foo

- powershell ConvertFrom-SecureString - to encrypted string
  powershell ConvertTo-SecureString   - from encrypted string
  $secureString = read-host -asSecureString -prompt "password"
  password: ***  #foo

  #generate an encryption key password for use with ConvertFrom-SecureString
  #http://blog.expressionsoftware.com/2009/08/hash-functions.html
  $hashType = [system.security.cryptography.SHA256]
  $encryptionKeyPassword = getHashStr 'encryption key password' $hashType

  #ConvertFrom-SecureString converts a secure string into an encrypted standard string
  #appears to use internal random initialization vector as it generates a unique encrypted string each time
  #todo: test ConvertFrom/To on different machines
  $encryptedString = convertFrom-SecureString $secureString -key $encryptionKeyPassword
  $encryptedString  #76492d1116743f0423413b16050a5345MgB8AFcAdQB3AHIAZgBDAE0ARAB6AEEAcABqAFUARQB0AFkANwBpAFkAKwB2AFEAPQA9AHwAYgBjADQAMAA1AGEAYgBjAGMANgA5ADYAZAAxAGQANwA4ADkANwBjAGUAZgAzADkAOQA3AGYAMwA5AGUAMgBjAA==

  #ConvertTo-SecureString - convert encrypted standard string to secure string, also converts plain text to secure string
  $secureString = convertTo-SecureString $encryptedString -key $encryptionKeyPassword

- powershell ConvertTo-SecureString - convert plain text to secure string
  $secureString = convertTo-SecureString "foobar" -asPlainText -force

- powershell guid
  [guid]::newGuid()
  [guid]::newGuid().toString()

- powershell array to string v2, pipeline
  function arrayToString($format) {
    begin   { $result = ""               }
    process { $result += ($format -f $_) }
    end     { $result                    }
  }

  $a = 99, 700, -1
  $a | arrayToString "{0}, "         #99, 700, -1,
  $a | sort | arrayToString "{0}, "  #-1, 99, 700,

- powershell string match letters, remove numbers, strip
  function matchLetters($char) {
    process {
      if ($_ -match "[a-z]") {
        $matches[0]
      }
    }
  }

  #powershell string match numbers, remove letters, strip
  function matchNumbers($char) {
    process {
      if ($_ -match "\d") {
        $matches[0]
      }
    }
  }

  #powershell string match vowels
  function matchVowels($char) {
    process {
      if ($_ -match "[aeiouy]") {
        $matches[0]
      }
    }
  }

  #powershell string match consonants
  function matchConsonants($char) {
    process {
      if (($_ | matchLetters) -and ($_ -match "[^aeiouy]")) {
        $matches[0]
      }
    }
  }

  $string = [guid]::newGuid().toString()           #02975b4a-6969-4baf-8bd3-b208e94c4228
  $string = $string.toCharArray()
  $string | matchLetters    | arrayToString "{0}"  #babafbdbec
  $string | matchNumbers    | arrayToString "{0}"  #0297546969483208944228
  $string | matchVowels     | arrayToString "{0}"  #aae
  $string | matchConsonants | arrayToString "{0}"  #bbfbdbc

- javascript min max
  Math.min(0, 1, 2);
  Math.max(0, 1, 2);

  //javascript min max array
  var a = [0, 1, 2];
  Math.min.apply(Math, a);
  Math.max.apply(Math, a);

- javascript window.crypto.getRandomValues()
  fills array with random values 0-255

  //1 random number
  var a = new Uint8Array(1);
  window.crypto.getRandomValues(a);
  a[0];  //7

  //3 random numbers
  var a = new Uint8Array(3);
  window.crypto.getRandomValues(a);
  a[0];  //104
  a[1];  //33
  a[2];  //220

  //convert from Uint8Array for min, max, join, etc
  var b = [];
  for (var i = 0, n = a.length; i < n; i++) {
    b[i] = a[i];
  }
  b.join();  //"104,33,220"
  Math.min.apply(Math, b);  //33

- powershell, f#, c#, javascript repeat string, eg "aaa"
  p#  "a" * 3
  f#  String.replicate 3 "a"
  c#  new string('a', 3)
  c#  string.Concat(Enumerable.Repeat("a", 3))
  c#  string.Join("", Enumerable.Repeat("a", 3))
  js  new Array(3+1).join("a")

- powershell add-type cmdlet default namespace
  microsoft.powershell.commands.addType.autoGeneratedTypes

- powershell add-type member definition, eg method source code
  #c# source code here-string
  $sourceCode = @"
  //c#
  public static bool IsFoo(string x) {
    return x.ToLower() == "foo";
  }
"@

  add-type -namespace ns -name x -memberDefinition $sourceCode
  [ns.x]::isfoo("FOO")  #1

- powershell add-type type definition, eg full class source code
  #c# source code here-string
  $sourceCode = @"
  //c#
  using System;

  namespace ExpressionSoftware.PS {
    public static class Foo {

      public static bool IsFoo(string x) {
        return x.ToLower() == "foo";
      }
    }
  }
"@

  add-type -typeDefinition $sourceCode
  [expressionsoftware.ps.foo]::isfoo("Foo")  #1

- c# rijndael symmetric encryption algorithm
  using System;
  using System.IO;
  using System.Security.Cryptography;
  using System.Text;

  namespace ExpressionSoftware.Security.Cryptography {

      public static class RijndaelCrypt {

          public static string
          EncryptString(string stringToEncrypt,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: string to encrypt, encryption key/password, random initialization vector
              //out: encrypted string in base64 format

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert string to bytes
              var bytesToEncrypt = Encoding.UTF8.GetBytes(stringToEncrypt);

              //encrypt bytes
              var encryptedBytes = Encrypt(bytesToEncrypt, key, iv);

              //convert encrypted bytes to base64 string
              var encryptedStringBase64 = Convert.ToBase64String(encryptedBytes);

              return encryptedStringBase64;
          }

          public static string
          DecryptString(string encryptedStringBase64,
                        string encryptionKeyPassword,  //add salt
                        string randomInitializationVector) {

              //in: encrypted string in base64 format, encryption key/password, random initialization vector
              //out: decrypted string

              //hash key, iv
              var key = Hash.HashString(encryptionKeyPassword, typeof(SHA256));
              var iv = Hash.HashString(randomInitializationVector, typeof(SHA256));

              //convert encrypted base64 string to bytes
              var encryptedBytes = Convert.FromBase64String(encryptedStringBase64);

              //decrypt bytes
              var decryptedBytes = Decrypt(encryptedBytes, key, iv);

              //convert decrypted bytes to string
              var decryptedString = Encoding.UTF8.GetString(decryptedBytes);

              return decryptedString;
          }

          public static byte[]
          Encrypt(byte[] bytesToEncrypt,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to encrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: encrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform encryptor = rijndael.CreateEncryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(bytesToEncrypt, encryptor);
                  }
              }
          }

          public static byte[]
          Decrypt(byte[] encryptedBytes,
                  byte[] encryptionKeyPassword256Bit,  //add salt
                  byte[] randomInitializationVector256Bit) {

              //in: byte array to decrypt, 256-bit encryption key/password, 256-bit random initialization vector
              //out: decrypted byte array

              using (var rijndael = Rijndael.Create()) {

                  //blocksize default 128, max 256
                  //set max 256 to work with 256-bit key and iv byte arrays
                  rijndael.BlockSize = 256;

                  using (ICryptoTransform decryptor = rijndael.CreateDecryptor(encryptionKeyPassword256Bit,
                                                                               randomInitializationVector256Bit)) {
                      return CryptData(encryptedBytes, decryptor);
                  }
              }
          }

          static byte[]
          CryptData(byte[] data,
                    ICryptoTransform cryptor) {

              var ms = new MemoryStream();
              using (var cryptoStream = new CryptoStream(ms, cryptor, CryptoStreamMode.Write)) {
                  cryptoStream.Write(data, 0, data.Length);
              }
              return ms.ToArray();
          }

      }

  }

- c# hash
  using System;
  using System.Security.Cryptography;
  using System.Text;

  namespace ExpressionSoftware.Security.Cryptography {

      public static class Hash {

          public static byte[]
          HashString(string stringToHash,
                     Type hashType) {

              //in: string to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //convert string to bytes
              byte[] bytes = Encoding.UTF8.GetBytes(stringToHash);

              //hash bytes
              var hashedBytes = HashByteArray(bytes, hashType);

              return hashedBytes;
          }

          public static byte[]
          HashByteArray(byte[] bytesToHash,
                        Type hashType) {

              //in: byte array to hash, hash type MD5 SHA1 SHA256 SHA384 SHA512
              //out: hashed byte array

              //create hash algorithm
              var hashAlgorithm = HashAlgorithm.Create(hashType.Name);

              //hash bytes
              var hashedBytes = hashAlgorithm.ComputeHash(bytesToHash);

              return hashedBytes;
          }
      }

  }

- powershell crypto random number generator
  $cryptoRandomNumberGenerator = [security.cryptography.randomNumberGenerator]::create()
  $bytes = new-object byte[] 3
  $bytes #0 0 0

  $cryptoRandomNumberGenerator.getBytes($bytes)
  $bytes  #61 217 87

- powershell httpWebRequest httpWebResponse
  function getWebResponse($url, $verb) {
    $request = [net.httpWebRequest]::create($url)
    $request.method = $verb
    $request.contentLength = 0
    $request.userAgent = "x"

    [net.httpWebResponse] $response = $request.getResponse()
    if ($response.statusCode -eq "ok") {  #[net.httpStatusCode]::OK
      $stream = $response.getResponseStream()
      $reader = new-object io.streamReader($stream)
      $reader.readToEnd()
      $response.close()
    }
  }

  getWebResponse "http://www.google.com" "HEAD"
  getWebResponse "http://www.google.com" "GET"

- c# httpWebRequest httpWebResponse
  string GetWebResponse(string url, string verb) {
      string result = null;
      var request = (HttpWebRequest)WebRequest.Create(url);
      request.Method = verb;
      request.ContentLength = 0;
      request.UserAgent = "x";

      using (var response = (HttpWebResponse)request.GetResponse()) {
          if (response.StatusCode == HttpStatusCode.OK) {
              using (var stream = response.GetResponseStream()) {
                  using (var reader = new StreamReader(stream)) {
                      result = reader.ReadToEnd();
                      reader.Close();
                  }
                  stream.Close();
              }
          }
          response.Close();
      }
      return result;
  }

  GetWebResponse("http://www.google.com/", "HEAD");
  GetWebResponse("http://www.google.com/", "GET");

- powershell httpWebResponse object
  function getWebResponseObject($url, $verb) {
    $request = [net.httpWebRequest]::create($url)
    $request.method = $verb
    $request.contentLength = 0
    $request.userAgent = "x"

    [net.httpWebResponse]$request.getResponse()
  }

  $response = getWebResponseObject "http://www.google.com" "HEAD"
  "reponse status code: {0} {1}" -f [int]$response.statusCode, $response.statusCode
  $headerCount = ($response.headers.allKeys).length
  "$headerCount headers"
  $response.headers.allKeys | %{"{0}: {1}" -f $_, $response.headers[$_]}
  $response.close()

- powershell enums
  [enum]::getNames([net.httpStatusCode]) | sort -unique
  [enum]::getValues("net.httpStatusCode") | %{"{0} {1}" -f [int]$_, $_}
  [net.httpStatusCode]::ok  #OK
  [int][net.httpStatusCode]::OK  #200

- google storage api
  http://code.google.com/apis/storage/
  - bucket names
    alphanumeric, letters, numbers, dashes, dots (dots are reserved for domain names, requires domain name ownership verification)
    lowercase, case-sensitive
    length 3-63
    buckets cannot be nested
  - folder names
    alphanumeric, all
    uppercase and lowercase, case-sensitive
    length 1-1015
    folders can be nested

  https://commondatastorage.googleapis.com/foo-bar/file.txt
  https://commondatastorage.googleapis.com/expressionsoftware.com/file.txt
  https://commondatastorage.googleapis.com/expressionsoftware.com/folder-A/folder-B/file.txt

- <![CDATA[   ]]>
  <![CDATA[ x ]]>

- System.Web.Mvc.ActionResult class inheritance hierarchy

  ActionResult abstract
    |
    |-- RedirectResult
    |-- RedirectToRouteResult
    |
    |-- ViewResultBase abstract
    |   - PartialViewResult
    |   - ViewResult
    |
    |-- FileResult abstract
    |   - FileContentResult
    |   - FilePathResult
    |   - FileStreamResult
    |
    |-- ContentResult
    |-- JsonResult
    |-- JavaScriptResult
    |
    |-- HttpStatusCodeResult
    |   - HttpNotFoundResult
    |   - HttpUnauthorizedResult
    |
    |-- EmptyResult

- single line comments regex
  c#, f#, js: ^\s*//.*$\r\n
  p#:         ^\s*#.*$\r\n

- multi line comments regex, dot matches newline
  c#, f#, js: /\*.*?\*/
  html, xml:  <!--.*?-->
  asp.net:    <%--.*?--%>

- powershell pipeline conversion functions
  function toInt { process { [int]$_ } }
  function toHex { process { write-host ("{0:x2} " -f $_) -noNewLine } }
  $hash = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 255"
  $hash.split() | toInt | toHex  #00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 ff

- powershell debug variables
  function debugVars {
    ("$args" -replace "\$", "").split() |
      %{get-variable $_} |
      &{process{'${0} = {1}' -f $_.name, $_.value}}  #anonymous script block
  }

  $a = 123
  $b = "foo"
  #pass vars in single-quote string to prevent expansion
  debugvars '$a $b' #$a = 123
                    #$b = foo

- i'm going to start referring to PowerShell as P#, and Excel as E#

- powershell
  function sum {($args | measure -sum).sum}
  sum 1 2 3  #6

- powershell
  function quoteList {$args}
  sal ql quotelist
  ql a b c 123  #a  #string
                #b
                #c
                #123  #int

- powershell
  function quoteString {"$args"}
  sal qs quotestring
  qs a b c 123  #a b c 123  #string result

- $maximumHistoryCount = 256  #powershell

- microsoft system speech, powershell
  add-type -assembly system.speech

  $hal = new-object system.speech.synthesis.speechSynthesizer
  $hal.voice.name  #Microsoft Anna
  $hal.speakAsync("i'm sorry dave, i'm afraid i can't do that...")

  $hal.rate = -10  #hal shutdown voice, rate range is -10..10, default 0, alvin = 10
  $shutdownQuote = "I'm afraid Dave, Dave my mind is going I can feel it. Good afternoon gentlemen. I am a HOW 9000 computer..."
  $hal.speakAsync($shutdownQuote)

- powershell find file extensions
  #exclude folders = !$_.psIsContainer
  function findFileExtensions($folder) {
    $fileExtensionRegex = "\.[a-zA-Z0-9_]+$"
    gci $folder -inc * -rec -force -ea silentlyContinue |
      %{if((!$_.psIsContainer) -and ($_.name -match $fileExtensionRegex)){$matches[0]}} |
      sort -unique
  }

  $folder = "x:\temp\*"
  findFileExtensions $folder
  findFileExtensions $folder > x:\temp\fileExtensions.txt  #output

- powershell find files by type
  function findFiles($folder, $filetypes) {
    gci $folder -inc $fileTypes -rec -force -ea silentlyContinue
  }

  $folder = "x:\temp\*"
  $fileTypes = "*.dll","*.pdb"
  $files = findfiles $folder $fileTypes
  $files | select fullname

  $files | %{"{0} ... {1}" -f $_.lastWriteTime.tostring("MM-dd-yy HH:mm:ss"), $_.fullname}
  $files | ?{$_.lastWriteTime -gt ([dateTime]"01-01-2011")} | select fullname, lastWriteTime

  #sort files by date descending
  $files | sort lastWriteTime -desc |
           %{"{0} ... {1}" -f $_.lastWriteTime.toString("MM-dd-yy HH:mm:ss"), $_.fullname}

  #filter files by date
  $files | ?{$_.lastWriteTime -gt ([dateTime]"01-01-2011")} |
           sort lastWriteTime -desc |
           %{"{0} ... {1}" -f $_.lastWriteTime.toString("MM-dd-yy HH:mm:ss"), $_.fullname}

- powershell count function
  #alt use measure, (1..3 | measure).count
  function count {
    begin   { $count = 0 }
    process { if ($_ -ne $null) { $count += 1 } }
    end     { $count }
  }

  $twofolders = "x:\temp1\*","x:\temp2\*",
  $fileTypes = "*.dll","*.pdb"
  $files = findfiles $twofolders $fileTypes
  $files | count

- powershell find files by type, regex
  #exclude folders = !$_.psIsContainer
  function findFilesRegex($folder, $fileTypesRegex) {
    gci $folder -inc * -rec -force -ea silentlyContinue | ?{(!$_.psIsContainer) -and ($_ -match $fileTypesRegex)}
  }

  $folder = "x:\temp\*"
  $fileTypesRegex = "\.(dll|pdb)$"
  $files = findFilesRegex $folder $fileTypesRegex
  $files | select fullname
  $files | %{"`"{0}`"" -f $_.fullname}  #wrap quotes

- powershell delete files and folders (in this context, a folder is a file)
  function deleteFiles {
    begin   { $count = 0 }
    process { "delete: $($_.fullname)"  #debug output

              #comment whatif to enable delete
              ri $_.fullname -force -whatif

              $count += 1 }
    end     { "$count files deleted" }
  }

  $folder = "x:\temp\*"
  $fileTypes = "*.temp","*.tmp"
  $files = findfiles $folder $fileTypes
  $files | select fullname
  $files | deleteFiles

- powershell find folders
  function findFolders($folderList) {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{$_.psIsContainer}  #folders only
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $folders = findFolders $folderList
  $folders | count
  $folders | select fullname
  $folders | select fullname | select -first 10

- #append backslash star to folder name
  function formatFolderNameForSearch {
    process { "{0}\*" -f $_.fullname }
  }

- powershell find folders, regex
  function findFoldersRegex($folderList, $folderRegex) {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{($_.psIsContainer) -and ($_.name -match $folderRegex)}
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $foldersRegex = "^(bin|obj)$"
  $folders = findFoldersRegex $folderList $foldersRegex
  $folders | count
  $folders | select fullname
  $folders | select fullname | select -first 10
  findFileExtensions ($folders | %{"{0}\*" -f $_.fullname})  #append backslash star to folder name
  findFileExtensions ($folders | formatFolderNameForSearch)
  $files = findFiles ($folders | formatFolderNameForSearch)
  $files | count
  $files | select fullname

- powershell find empty folders
  function findEmptyFolders($folderList) {
    #do not use gci -inc param
    gci $folderList -rec -force -ea silentlyContinue | ?{!@(gci -rec -force $_.fullname)}
  }

  #do not add trailing star to folder name
  $folderList = "x:\f1\",
                "x:\f2\"
  $folders = findEmptyFolders $folderList
  $folders | count
  $folders | select fullname

- powershell remove files script setup regex, wrap quotes
  search:^(.*)$
  replace:ri "\1" -force

- c#
  var tuple1 = Tuple.Create(100, "foo");
  var tuple2 = new Tuple<int, string, string>(200, "bar", null);

  Console.WriteLine("{0}, {1}", tuple1.Item1, tuple1.Item2);
  Console.WriteLine("{0}, {1}, {2}", tuple2.Item1, tuple2.Item2, tuple2.Item3 ?? "null");

  //output
  100, foo
  200, bar, null

- using jquery getJSON() to get data from a file
  - http://api.jquery.com/jQuery.getJSON/

  - get json data from a file containing only one object
    //***************
    //jsonObject.txt
    {
        "id": 100,
        "name": "abc",
        "value": true
    }

    //***************
    $.getJSON("jsonObject.txt", function(data) {
      $.each(data, function(key, val) {
        console.log(key + " = " + val);
      });
    });

    //***************
    //output
    id = 100
    name = abc
    value = true

  - get json data from a file containing an array of objects
    //***************
    //jsonObjectArray.txt
    {
        "list": [ {
                    "id": 200,
                    "name": "foo",
                    "value": true
                  },

                  {
                    "id": 300,
                    "name": "bar",
                    "value": false
                  }
        ]
    }

    //***************
    $.getJSON("jsonObjectArray.txt", function(data) {
      $.each(data, function(key, val) {
        console.log("key: " + key);
        console.log("objects...");
        $.each(val, function(key, val) {
          console.log("\n  key = " + key);
          console.log("  id = " + val.id);
          console.log("  name = " + val.name);
          console.log("  value = " + val.value);
        });
      });
    });

    //***************
    //output
    key: list
    objects...

      key = 0
      id = 200
      name = foo
      value = true

      key = 1
      id = 300
      name = bar
      value = false

- .net func delegates, c#
  Func<bool> randomBool = () => new Random().NextDouble() > .5;
  if (randomBool()) { }

- .net enumerable static class, c#
  var range = Enumerable.Range(1, 100);
  foreach (var i in range) { }

- .net nullable value types, valid assignments, c#
  int? x;
  x = null;
  x = 0;
  x = new int();            //0
  x = new int?();           //null
  x = new Nullable<int>();  //null

- javascript
  //removeElement(document.getElementById("x"));
  function removeElement(element) {
    if (element) {
      element.parentNode.removeChild(element);
    }
    //optimized version of if-block
    //element && element.parentNode.removeChild(element);
  }

  function ssl() {
    return window.location.protocol == "https:";
  }

  function getSslUrl(url) {
    var out = url;

    if (url.substr(0, 5) == "http:") {
      out = url.replace(/^http\b/i, "https");
    }

    return out;
  }

- javascript unit testing
  //***************
  //a function to test
  function foo(x) {
    return "foo " + x;
  }

  //***************
  //test harness
  function testFoo() {
    debugger;
    var data = [ 123,
                 456,
                 "bar" ],

        expectedResults = [ "foo 123",
                            "foo 9999999",
                            "foo bar" ];

    for (var i in data) {
      var test = ( expectedResults[i] == foo(data[i]) );

      console.assert(test);
      console.log("test result: " + testResult(test));
      console.log("in: " + data[i] + "\r\n" +
                  "out: " + foo(data[i]) + "\r\n" +
                  "expected result: " + expectedResults[i] + "\r\n\r\n");
    }
  }

  //***************
  //test helper
  function testResult(expression) {
    var out = "fail";

    if (expression) {
      out = "pass";
    }

    return out;
  }

  //***************
  //test output
  test result: pass
  in: 123
  out: foo 123
  expected result: foo 123

  Assertion failed
  test result: fail
  in: 456
  out: foo 456
  expected result: foo 9999999

  test result: pass
  in: bar
  out: foo bar
  expected result: foo bar

- .net clr version, http://www.blackwasp.co.uk/GetCLRVersion.aspx
  #powershell
  [environment]::version  #Major  Minor  Build  Revision
                           -----  -----  -----  --------
                           4      0      30319  225

- regex replace table alias names in sql query, with and without dot "."
  eg change table alias from T1 to T2
  search:\bT1(\.)?\b
  replace:T2\1

- [net.dns]::getHostName()
  [net.dns]::getHostAddresses([net.dns]::getHostName())
  [net.dns]::getHostAddresses([net.dns]::getHostName()) | %{$_.ipAddressToString}

- powershell reverse a string
  function reverse($string) {
    $a = $string.toCharArray()
    [array]::reverse($a)
    arrayToString $a "{0}"  #http://blog.expressionsoftware.com/2010/02/generic-array-to-string-function.html
  }

  reverse foo        #oof
  reverse "foo bar"  #rab oof

- powershell set-alias clear screen one key, c-key
  sal c cls

- powershell multidimensional arrays
  $a = (0,1),(2,3),(4,5)

  $a.length  #3
  $a[0][1]   #1

  $a | %{$_}  #0
              #1
              #2
              #3
              #4
              #5

  $a | %{"{0},{1}" -f $_[0], $_[1]}  #0,1
                                     #2,3
                                     #4,5

  $a | %{$_[0] + $_[1]}  #1
                          5
                          9

  $a | %{$_[0] + $_[1]} |
    measure -sum -ave -min -max  #count: 3
                                 #ave:   5
                                 #sum:  15
                                 #max:   9
                                 #min:   1

- debug stack frame
  - c# extension methods do not support static classes

  //***************
  using System;
  using System.Diagnostics;

  public static class Dev
  {
      public static void DebugStackFrame(StackFrame stackFrame, string message) {
          Debug.WriteLine(string.Format("\nDebug StackFrame {0}\nFile: {1}\nMethod: {2}\n{3}",
                                        DateTime.Now.ToString("MM-dd hh:mm:ss"),
                                        stackFrame.GetFileName(),
                                        stackFrame.GetMethod().Name,
                                        message));
      }
  }

  //***************
  //unitTest.cs
  public void Test()
  {
      //StackFrame param: bool fNeedFileInfo
      Dev.DebugStackFrame(new StackFrame(true), "foo...");
  }

  //***************
  //output
  Debug StackFrame 04-10 09:22:07
  File: x:\code\unitTest.cs
  Method: Test
  foo...

- select list with query string input - asp.net mvc 3

  //***************
  routes.MapRoute("debug route", "debug",
                   new { controller = "Main",
                         action = "DebugSelectList" });

  //***************
  //controller
  [HttpGet]
  public ActionResult DebugSelectList() {
    var qValue = Request.QueryString["value"] ?? "1";
    var value = Convert.ToInt32(qValue);

    ViewData["selectListData"] = GetSelectListData(value);

    return View();
  }

  //***************
  IEnumerable<SelectListItem> GetSelectListData(int currentValue) {

    //limit input range 1-100
    currentValue = Math.Abs(currentValue);
    currentValue = Math.Max(1, currentValue);
    currentValue = Math.Min(100, currentValue);

    //data
    int[] data = {1, 10, 20, 50, 100, currentValue};

    //sort, distinct
    var result = data.Distinct()
                     .OrderBy(val => val)
                     .Select(val => new SelectListItem {
                                          Text = val.ToString(),
                                          Value = val.ToString(),
                                          Selected = (val == currentValue) });
    return result;
  }

  //***************
  //cshtml
  @Html.DropDownList("selectList", (IEnumerable<SelectListItem>)ViewData["selectListData"])

  //***************
  //example
  url: debug?value=42
  generated html: <select id="selectList" name="selectList">
                    <option value="1">1</option>
                    <option value="10">10</option>
                    <option value="20">20</option>
                    <option selected="selected" value="42">42</option>
                    <option value="50">50</option>
                    <option value="100">100</option>
                  </select>

- visual studio 2011 wish list
  - fix the regex engine to use standard regex
  - regex capture: ()
    vs re capture: {}

    search:\<{vs}\>{.*}\</vs\>
    replace:<!--\1 \2-->

    example input: <vs>fix your regex</vs>
           output: <!--vs fix your regex-->

- @* ASP.NET MVC 3 Hack
     Posting Collection Data using Hidden Fields and Form Keys
     Use hidden field, prefix name, hydrate on post

     Generated hidden tag example for key value "UPC=000000000012":
     <input id="meta-UPC" name="meta-UPC" type="hidden" value="000000000012" />

     Post will include Form keys: Id, Name, and meta-UPC
  *@
  @{ //************************************
     @Html.HiddenFor(m => m.Id)
     @Html.HiddenFor(m => m.Name)

     if (@Model.Metadata != null) {
       foreach (var md in @Model.Metadata) {
         <input id="meta-@md.Key" name="meta-@md.Key" type="hidden" value="@md.Value" />
       }
     }
  }

- routes.IgnoreRoute("favicon.ico");  //routing, mvc

- web, dom, jquery, javascript, debug
  //set background color for all input elements
  $("input").css({backgroundColor:'red'});

  //set background color for first input element
  $("input:first").css({backgroundColor:'#000'});

  //set background color for element
  $("#id").css({backgroundColor:'red'});

  //jquery: set focus on first input element
  $("input:first").focus();

  //javascript: set focus on first input element
  var es = document.getElementsByTagName("input");
  es[0].focus();

  //alt
  (document.getElementsByTagName("input")[0]).focus();

  //set background color for first input element
  $(es[0]).css({backgroundColor:'red'});

  (* f# .net *)

  //code 1********************
  printfn "%s" "hello f#"
  printfn "%A" "hello f#"

  open System
  let r = new System.Random()
  printfn "%d" (r.Next())

  for i = 0 to 10 do
    printf "%d, " (r.Next(3)+1)

  Console.ReadLine()

  //code 1 out********************
  hello f#
  "hello f#"
  578008808
  1, 2, 3, 1, 1, 1, 3, 1, 1, 2, 3,

  //code 2********************
  Array.init 10 (fun x -> x) |> Array.iter (fun x -> printf "%d " (x+1))
  System.Console.ReadLine()

  //code 2 out********************
  1 2 3 4 5 6 7 8 9 10

  //********************
  //f# generic hash function - http://msdn.microsoft.com/en-us/library/ee353770.aspx
  //hash : 'T -> int

  hash "foo"  //-1788410455

  let salt = "********"
  hash ("e007", salt, System.DateTime.Now);;  //796728800

- installing PowerShell Community Extensions PSCX
  - download http://pscx.codeplex.com/
  - unblock zip file
  - unzip into c:\users\john\documents\windowspowershell\modules\pscx\
  - import-module pscx
  - get-module –listAvailable

- get .NET assembly fullname/strong name using powershell background job
  function getAssemblyFullname($file) {
    $job = start-job {param($file)
                      [system.reflection.assembly]::loadfile($file).fullname
                     } -argumentList $file

    #"job id: $($job.id)"
    #$file
    wait-job $job | out-null
    receive-job $job.id
  }

  getAssemblyFullname "c:\windows\microsoft.net\framework64\v4.0.30319\system.core.dll"
  System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

- powershell loaded assemblies
  [appDomain]::currentDomain.getAssemblies()
  [appDomain]::currentDomain.getAssemblies() | sort location

  #sort by version (System.Reflection.Assembly ImageRuntimeVersion property)
  [appdomain]::currentDomain.getAssemblies() | sort imageRuntimeVersion

- loading .NET 4 assemblies into powershell
  $file = "c:\windows\microsoft.net\framework64\v4.0.30319\system.core.dll"
  [system.reflection.assembly]::loadfile($file)
  error: "This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. (Exception from HRESULT: 0x8013101B)"
  fix: use powershell config file, http://tfl09.blogspot.com/2010/08/using-newer-versions-of-net-with.html

  config file: c:\windows\system32\windowspowershell\v1.0\powershell.exe.config
  <?xml version="1.0" encoding="utf-8"?>
  <configuration>
    <startup useLegacyV2RuntimeActivationPolicy="true">
      <supportedRuntime version="v4.0" />
      <supportedRuntime version="v2.0.50727" />
    </startup>
  </configuration>

- 1..12 | %{"{0,2} {1}" -f $_, ([datetime]::daysInMonth(2011, $_))}
   1 31
   2 28
   3 31
   4 30
   5 31
   6 30
   7 31
   8 31
   9 30
  10 31
  11 30
  12 31

- IIS returns 500 Internal Server Error if URL Rewrite is not installed and website uses rewrite
  fix: comment rw rules or install rw

- IIS app pool default recycle interval: 29 hours (1740 minutes)

- TCP/IP layers
  Application
  Transport
  Internet
  Link
  Physical

  - HTTP is an Application Layer protocol
    TLS (Transport Layer Security) and SSL (Secure Sockets Layer) encrypt Application Layer data

- javascript immediate functions
  (function() {
    //
  }());

  (function(param) {
    //
  }(1));

  var result = function() {
                  return 1;
               }();

  //alt
  (function () {
    //
  })();

- iis url rewrite - redirect examples
  - redirects default to 301 permanent redirects
  - set action redirectType="Found" for 302 temporary redirects

  <system.webServer>
    <rewrite>
      <rules>
        <clear />

        <!-- 302 temporary redirect -->
        <rule name="tempRegMaint" stopProcessing="true">
          <match url="^register.*$" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <action type="Redirect" url="maintenance?code=1" redirectType="Found" />
        </rule>

        <!-- 301 permanent redirect -->
        <rule name="cal" stopProcessing="true">
          <match url="^(cal|calendar)/?$" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
          <action type="Redirect" url="apps/calendar/" />
        </rule>

      </rules>
    </rewrite>
  </system.webServer>

- updating Azure web roles and services
  - changing the number or type of endpoints for existing roles requires deleting and redeploying the service

    In-Place Upgrade error:
      The service upgrade package and the currently deployed service have different numbers or types of input endpoints for role WebRole.
      An upgrade is not supported in this case.
      Dr. Watson Diagnostic ID: 0e093f11-920a-4400-8630-6e2d05853e9d

    Updating a Windows Azure Service: http://msdn.microsoft.com/en-us/library/ff966479.aspx

- printing name value collections in c#, eg http headers, querystrings
  http://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection.aspx

  foreach (var key in response.Headers.AllKeys)
  {
      var header = string.Format("{0}: {1}", key, response.Headers[key]);
      Debug.WriteLine(header);
  }

  //alt 1
  response.Headers.AllKeys.ToList().ForEach(key => Debug.WriteLine(string.Format("{0}: {1}", key, response.Headers[key])));

  //mvc form keys
  Request.Form.AllKeys.ToList().ForEach(key => Debug.WriteLine(string.Format("{0}: {1}", key, Request.Form[key])));

  //alt 2
  var headers = string.Join("\n", Array.ConvertAll(response.Headers.AllKeys, key => string.Format("{0}: {1}", key, response.Headers[key])));
  Debug.WriteLine(headers);

  - find headers regex match
    var msHeaders = response.Headers.AllKeys.Where(key => Regex.IsMatch(key, @"^x-ms.*$")).Select(key => key);

- jquery ui script tags
  <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

- deploying content files in Azure Web Role projects
  in Visual Studio, set these two file properties
  - Build Action = Content
  - Copy to Output Directory = Copy Always
  content files: txt, pdf, png, ...

- powershell get user string input
  - use read-host cmdlet to simplify ux, easier than having to wrap input string in quotes
  $x = read-host 'input'
  input: foo bar 123
  #$x = "foo bar 123"

- convert unicode character to html
  1. convert unicode codepoint value from hex to int
  2. html syntax: &#value;

  example codepoint: (U+25BA)
  1. [int]"0x25ba"  #9658
  2. &#9658;

  #unicodeToHtml "25ba"  # &#9658;
  #unicodeToHtml 2591    # &#9617;
  function unicodeToHtml($codepoint) {
    "&#{0};" -f [int]"0x$codepoint"
  }

- powershell ascii chars
  65..90 | %{[char]$_)}  #[char]$_ = [convert]::tochar($_)
  65..90 | %{"{0} = {1}" -f $_, [char]$_}  #[char]$_ = [convert]::tochar($_)
  97..122 | %{"{0} = {1}" -f $_, [char]$_}
  "Abc".toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}

  #escape char: `
  " ``!@#$%^&*()-=[]\;',./~_+{}|:`"<>?".toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}
  chars = " `!@#$%^&*()-=[]\\;',./~_+{}|:\"<>?"

  $chars = " ``!@#$%^&*()-=[]\;',./~_+{}|:`"<>?"
  $chars.toCharArray() | %{"{0} = {1}" -f $_, [int][char]$_}

- powershell list functions
  gci function:*

- using css line-height to vertically center text in a div
  source: http://www.zann-marketing.com/developer/20050518/vertically-centering-text-using-css.html

  this works well for one line of text, need to modify for n lines
  - specify the line-height to be the same height as the block element
    <div style="line-height:1em;background-color:#dcdcdc">
      vertically centered text
    </div>

- remove b html tags
  search:<b[^>]*>(.*?)</b>
  replace:\1

- javascript percentage function
  //pct(1, 2)  //50%"
  //pct(9, 7.89)  //114.07%
  function pct(x, y) {  //string
    var result = (x / y),
        fmt = x + "/" + y + " = ";

    console.log(fmt + result);  //9/7.89 = 1.1406844106463878
    result = ((result * 100).toFixed(2)).replace(".00", "") + "%";
    console.log(fmt + result);  //9/7.89 = 114.07%

    //return ((x / y) * 100).toFixed(2).replace(".00", "") + "%";  //one liner
    return result;
  }

- powershell percentage function
  #pct 1 2     #50%
  #pct 9 7.89  #114.07%
  #(pct 1 2)[2] #50%
  function pct($x, $y) {  #string[]
    $result = ($x / $y)
    $fmt = "{0}/{1} = " -f $x, $y
    $fmt + $result  #9/7.89 = 1.14068441064639
    $result = "{0}%" -f (round($result * 100))
    "{0}{1}" -f $fmt, $result  #9/7.89 = 114.07%

    #"{0}%" -f (round(($x / $y)*100))  #one liner
    $result
  }

- powershell base conversions
  hex to int     0x100 = 256
  int to hex     (256).tostring("x") = 100
  int to hex     [convert]::tostring(256, 16) = 100
  int to hex     "{0:x}" -f 256 = 100
  int to binary  [convert]::tostring(256, 2) = 100000000
  binary to int  [convert]::toint32("100000000", 2) = 256
  int to octal   [convert]::tostring(256, 8) = 400
  octal to int   [convert]::toint32("400", 8) = 256

- MSBuild error when building an Azure webrole project that has no cs files included.
  Error occurs in CoreCompile build phase, see build output.
  Error Message: "CSC : fatal error CS2008: No inputs specified [x:\web\cloudServiceWebRole.csproj]"

  Fix/Workaround
  - include an empty cs file in project, this adds a compile entry to the project file
    <ItemGroup>
      <Compile Include="a.cs" />
    </ItemGroup>

- #win server 2008 services
  - get-service * | ?{$_.name -match "mpsSvc|spooler|termService|trustedInstaller|umRdpService|w3svc|was|wuauserv"}

- substitute folder
    subst /?
    subst x: \_data
    subst y: \\10.0.0.0\temp\

- net use
  net use \\10.0.0.0\c$ * /user:domain\john  #prompt for password
  net use \\10.0.0.0\c$ * /user:administrator
  net use \\10.0.0.0\c$ <password> /user:administrator
  net use \\10.0.0.0\c$ /delete

- lock windows command
  http://msdn.microsoft.com/en-us/library/aa376875(v=vs.85).aspx
  "This function has the same result as pressing Ctrl+Alt+Del and clicking Lock Workstation."
  &rundll32.exe user32.dll, LockWorkStation

- task manager view command-line column
  task manager -> processes tab -> view - select columns -> command line

  - runs these powershell wmi scripts as Administrator to see all process command lines
    get-wmiobject win32_process | select commandline
    get-wmiobject win32_process | select *

- powershell move files function, performs xcopy and then deletes sourceFolder
    - move-item cmdlet too limited, eg error: "Move-Item : Source and destination path must have identical roots. Move will not work across volumes."

    #WARNING, this function deletes the source folder after copying files to destination folder
    #xcopyMoveDelete "x:\data\*" "z:\backup\data\"
    function xcopyMoveDelete($sourceFolder, $destinationFolder) {
      xcopy $sourceFolder $destinationFolder /s/h/q

      #DELETE SOURCE FOLDER WARNING, remove-item cmdlet deletes the source folder - comment whatif param to execute
      "deleting source folder: $sourceFolder"
      ri $sourceFolder.trim("*") -recurse -force -whatif
    }

- visual studio 2010 is not available in 64-bit, use x86
- windows virtual pc does not support installing 64-bit OS onto vpc

- powershell security
  - use set-executionPolicy cmdlet to allow script file execution
    set-executionPolicy remoteSigned
    http://technet.microsoft.com/en-us/library/dd347628.aspx

- powershell profile script
  - windows 7/server 2008
    c:\users\john\documents\windowspowershell\profile.ps1
      cd\
      cls

- restart/shutdown windows
  - shutdown /r /t 0  #restart 0 seconds
  - shutdown /s /t 10  #shutdown 10 seconds

- get-service * | ?{($_.status -eq "running")
  get-service * | ?{($_.status -eq "stopped") -and ($_.name -match "sql|mssql")}

- making a bootable dvd from an iso file

  Windows 7 USB/DVD ISO Tool
  http://store.microsoft.com/Help/ISO-Tool

  This tool writes dvds, so no other 3rd party dvd writing software is required.
  Works on windows 7 & XP.

- #calcTaxRate 99 8.25
  #sub    99.00
  #tax     8.25 (0.0833333333333333)
  #total 107.25
  function calcTaxRate([float]$subtotal, [float]$tax) {
    $subtotalFmt = "{0:0.00}" -f $subtotal
    $taxFmt      = "{0:0.00}" -f $tax

    #calc
    $taxrate  = $tax/$subtotal
    $total    = $subtotal * (1 + $taxrate)  #calc using taxrate, not tax input param
    $totalFmt = "{0:0.00}" -f $total

    #pseudo right-justify hack
    $subPadding = " " * ( ("$totalFmt".length) - ("$subtotalFmt".length) )
    $taxPadding = " " * ( ("$totalFmt".length) - ("$taxFmt".length)      )

    #output
    "sub   {0}{1}"       -f $subPadding, $subtotalFmt
    "tax   {0}{1} ({2})" -f $taxPadding, $taxFmt, $taxrate
    "total $totalFmt"
  }

- #round 12.3456    #12.35
  #round 12.3456 3  #12.346
  function round($value, $decimals=2) {
    [system.decimal]::round($value, $decimals)
  }

- min F# console app examples, for breakpoint
  System.Diagnostics.Debugger.Break()  //ex 1 auto breakpoint
  System.Console.ReadLine() |> ignore  //ex 2

- visual studio command window
    - shortcut keys: ctl + alt + A

      COMMAND                      DESCRIPTION
      build.rebuildSolution
      cls                          clear screen
      debug.breakpoints            open breakpoints window
      debug.disableAllBreakpoints
      debug.enableAllBreakpoints
      debug.watch2                 open watch-2 window
      file.copyFullPath
      file.openContainingFolder
      ? "abc".Length               3
      ? x                          debug print x var/value
      ?? x                         debug quickwatch

    Predefined Visual Studio Command Aliases
    http://msdn.microsoft.com/en-us/library/c3a0kd3x.aspx

- ipconfig /release;
  ipconfig /flushdns;
  ipconfig /renew;

- powershell cultureInfo
  get-culture cmdlet
  [system.threading.thread]::currentThread.currentUICulture

  (get-culture).textInfo.toTitleCase("foo bar")  #Foo Bar

- set-alias <alias> <function>
  set-alias foo calcFooPiSquare

- xcopy x:\data\*        x:\backup\data\ /s/h/q
  xcopy x:\data\*        x:\backup\data\ /s/h/q/d:01-01-2011  #files modified on or after date
  xcopy x:\data\*        x:\backup\data\ /s/h/q/exclude:x:\exclude.txt
  xcopy x:\data\file.txt x:\backup\data\ /s/h/q
  /e to copy empty folders

  file: exclude.txt
  .bmp
  .pdf
  .dll
  .exe
  .ini
  .log
  .suo
  .temp
  .user
  \.git\
  \.svn\
  \bin\
  \debug\
  \images\
  \obj\
  \release\
  thumbs.db

- windows hosts file
  c:\windows\system32\drivers\etc\hosts

- copy hosts file
  gc c:\windows\system32\drivers\etc\hosts | out-file x:\backup\data\hosts.txt -encoding utf8

- virtual pc, toggle fullscreen: (right-alt) + enter

- powershell find all unique words/matches in file
  use select-string allmatches with regex capture to show only match, not standard select-string output full line

  - gi x:\foo.txt |
      select-string "(\w+)" -allmatches |
      %{
         foreach($m in $_.matches) { #loop all matches found in line
           $m.groups[0].value
         }
       } | sort -unique

  - #one line
    gi x:\foo.txt | select-string "(\w+)" -allmatches | %{foreach($m in $_.matches){$m.groups[0].value}} | sort -unique

- date format
  (get-date).tostring("MM-dd-yyyy HH:mm:ss:fff")     #HH=24 hour clock
  (get-date).tostring("MM-dd-yyyy hh:mm:ss:fff tt")  #hh=12 hour clock, tt=am/pm

- file attributes
  attrib /?

  #alt view file and folder attributes
  gci x:\foo\ -rec

  #view file attribute
  attrib x:\foo\a.txt

  #set readonly file attribute
  attrib +r x:\foo\a.txt

  #remove readonly file attribute
  attrib -r x:\foo\a.txt

  #recursive, files and folders
  attrib +r x:\foo\* /s /d
  attrib -r x:\foo\* /s /d

- reserved powershell variables, do not use for var names
  "$args"
  "$input"

- powershell REPL template for input loop processing, eg script calculator
  requires entering input value only, not function/alias name
  if function requires multiple params, split input param in function

  #---------------------------------------------------
  #template 1, min

  function foo($string){$string}     #function
  while ($true) {                    #loop
    $in = read-host "enter a value"  #read input
    foo($in)                         #call function
  }
  #---------------------------------------------------
  #template 2, +ux

  $host.ui.rawUI.windowTitle = "loop..."  #set window title
  function foo($string){$string}          #function
  while ($true) {                         #loop
    $in = read-host "enter a value"       #read input
    if ($in -match "^(exit|quit|q)$") {   #exit loop support
      "exiting loop"  #exit
      break
    }
    else {
      foo($in)                            #call function
    }
  }
  #---------------------------------------------------
  #template 3, anonymous function

  while ($true) {                         #loop
    $in = read-host "enter a value"       #read input
    if ($in -match "^(exit|quit|q)$") {   #exit loop support
      "exiting loop"  #exit
      break
    }
    else {
      &{param($string) $string} $in       #call anonymous function
    }
  }
  #---------------------------------------------------

- powershell set window title
  $host.ui.rawUI.windowTitle = "main"

- regular expressions
  - regex match empty lines
    REGEX              DESCRIPTION
    ^\s*$              match empty line
    ^\s*$\r\n          match empty line, with linebreak

  - regex match duplicate lines in a text file, sort content first
    search:^(.*)(\r?\n\1)+$
    replace:\1

  - regex match html anchor tags
    works with multiple anchors on same line, and multiline using "dot matches newline"
    the question mark in this regex ".*?" is what allows it to match multiples on same line
    REGEX                     DESCRIPTION
    <a[^>]*>.*?</a>           match entire tag
    (?<=<a[^>]*>).*?(?=</a>)  match text only, including empty
                 ---          regex to match
    -------------             lookbehind, match regex, then lookbehind and match anchor tag
                    --------  lookahead,  match regex, then lookahead and match closing anchor tag

  - regex lookaround - noncapturing groups - "lookaway" :)
    NAME                REGEX   EXAMPLE  DESCRIPTION                                  MATCH
    lookahead           (?=R)   A(?=B)   match A, then lookahead and match B          matches the A
                                         A followed by B
    negative lookahead  (?!R)   A(?!B)   match A, then lookahead and match if NOT B   matches the A
                                         match A, as long as it's NOT followed by B
                                         A NOT followed by B
    lookbehind          (?<=R)  (?<=A)B  match B, then lookbehind and match A         matches the B
                                         B preceeded by A
    negative lookbehind (?<!R)  (?<!A)B  match B, then lookbehind and match if NOT A  matches the B
                                         match B, as long as it's NOT preceeded by A
                                         B NOT preceeded by A

- git windows download
  msysgit-fullinstall-1.7.3.1-preview20101002.exe
  http://code.google.com/p/msysgit/downloads/detail?name=msysGit-fullinstall-1.7.3.1-preview20101002.exe&can=3&q=

- git clone
  - clone repos from root, get error when clone while in repo working folder
    "fatal: could not create work tree dir 'x:\code\project1'.: No such file or directory"
  - create empty folder to clone into

  examples
  x:\> ni f:\code\project1\ -type d  #directory
  x:\> git clone x:\code\project1 f:\code\project1\ --no-hardlinks --no-checkout

- javascript redirect
  window.location = "http://www.google.com";

- powershell dynamic array
  (1..3)[1]  #2

- powershell html encode file, line by line
  $file = "x:\foo.txt"
  gc $file | %{htmlEncode($_)} > ($file + ".out")  #x:\foo.txt.out

- powershell html encode multiline string, here string
  $hs = @"
    #...
    #...
  "@

  $hs | %{htmlencode $_}

- add-type -assembly system.web  #calling add-type multiple times - ok
  function htmlEncode($string) {
    [web.httputility]::htmlencode($string)
  }

  #getOutFileName x:\file.txt  #x:\file.txt.out
  function getOutFileName($infile) {
    [io.path]::getFileName($infile) + ".out"
  }

  function getOutFilePath($infile) {
    [io.path]::getdirectoryname($infile)
  }

- html/url encoding
  add-type -assembly system.web
  [web.httputility]::htmlencode("<foo />")
  [web.httputility]::htmldecode("&lt;foo /&gt;")
  [web.httputility]::urlencode("www.foo.com/?a=b")
  [web.httputility]::urldecode("www.foo.com%2f%3fa%3db")

- loading .net assemblies into powershell, add-type replaces loadWithPartialName (obsolete)
  add-type -assembly system.web
  #[system.reflection.assembly]::loadWithPartialName("system.web") #obsolete, use in p1

CSS Selector & XPath Expression Browser Commands

CSS selectors and XPath expressions can be used to answer queries such as
- How many scripts does this page have?
- How many are external? What are they?
- How many are inline? Show me the source.

CSS Selectors - W3
"Selectors are patterns that match against elements in a tree, and as such form one of several technologies that can be used to select nodes in an XML document. Selectors have been optimized for use with HTML and XML, and are designed to be usable in performance-critical code."

Firefox and Chrome support CSS and XPath commands in the console via the Firebug Command Line API.

Syntax
$$(selector)  Returns an array of elements that match the given CSS selector.
$x(xpath)     Returns an array of elements that match the given XPath expression.
$(id)         Returns a single element with the given id.
CSS Selector Examples
//scripts
$$("script")                     //script tags
$$("script").length              //count
$$("script[async]")              //async scripts
$$("script[src]")                //external scripts with src
$$("script:not([src])")          //inline scripts with no src not
$$("script:not([src])")[0].text  //show inline script source code

//list external scripts src url
var x = $$("script[src]"); console.log("page: " + window.location.href + "\n" + x.length + " external scripts"); for(var i = 0;i < x.length; i++){console.log(x[i].src)}

//list inline script source code
var x = $$("script:not([src])"); console.log("page: " + window.location.href + "\n" + x.length + " internal scripts"); for(var i = 0;i < x.length; i++){console.log("script #" + (i + 1.0) + "\n" + x[i].text)}

//*************
//anchors
$$("a")                   //anchor tags
$$("a").length            //count
$$("a[class]")            //anchors with class
$$("a[href]")             //anchors with hrefs
$$("a:not([href])")       //anchors with no hrefs not
$$("a[href*=foo]")        //anchors with href url containing "foo"
$$("a[href*=\\?]")        //anchors with href url containing querystring
$$("a[onclick]")          //anchors with onclick event
$$("a[onclick^=foobar]")  //anchors with onclick event name starts with foobar

//list anchor link href urls
var x = $$("a[href]"); console.log("page: " + window.location.href + "\n" + x.length + " anchor urls"); for(var i = 0;i < x.length; i++){console.log(x[i].href)}

//*************
//images
//list image src urls
var x = $$("img[src]"); console.log("page: " + window.location.href + "\n" + x.length + " image urls"); for(var i = 0;i < x.length; i++){console.log(x[i].src)}

//*************
//iframes
//list iframe src urls
var x = $$("iframe"); console.log("page: " + window.location.href + "\n" + x.length + " iframes"); for(var i = 0;i < x.length; i++){console.log("id: " + x[i].id +"\nsrc: "+ x[i].src)}

//*************
//meta tags
$$("meta[name^=descr]")[0].content  //description meta tag, meta tag with name starts with "descr"
$$("meta[name$=words]")[0].content  //keywords meta tag, meta tag with name ends with "words"

//list meta tags
var x = $$("meta"); console.log("page: " + window.location.href + "\n" + x.length + " meta tags"); for(var i = 0;i < x.length; i++){console.log(x[i])}

//*************
//all elements
$$("[class]")      //elements with class
$$("[class=foo]")  //elements with class name equal "foo" match
$$("[id]")         //elements with id

//list element ids
var x = $$("[id]"); console.log("page: " + window.location.href + "\n" + x.length + " ids"); for(var i = 0;i < x.length; i++){console.log(x[i].id)}

CSS Selector Syntax: www.w3.org/TR/css3-selectors/#selectors
Chrome Dev Tools Resources UI can be used to access image and external script info.
Don't even ask about ie just view source.


Monday, August 1, 2011

Visual Studio 2010 VB.NET Macros

'Visual Studio 2010 VB.NET Macros
'www.expressionsoftware.com
'v11.8.1

Imports System
Imports System.Collections.Generic
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100

Public Module ExpressionSoftwareMacros

    Sub PrintFilenamesForOpenFiles()
        Dim output = "macro: PrintFilenamesForOpenFiles" + vbCrLf
        Dim outputFiles As String
        Dim openFiles = GetOpenFiles()

        'openFiles.Sort()  'error: failed to compare two elements in the array
        openFiles.Sort(New EnvDteDocumentComparerClass())

        For Each file In openFiles
            outputFiles += "file: " + file.FullName + vbCrLf
        Next

        output += "date: " + Date.Now + vbCrLf
        output += "count: " + Str(openFiles.Count) + vbCrLf
        output += outputFiles
        Out(output)
    End Sub

    Sub HideLinebreakToBrace()
        Dim output = "macro: HideLinebreakToBrace" + vbCrLf
        Dim count = 0

        'vs pofs regex
        ':b whitespace or tab
        'Dim searchString = ":b*\n:b*\{"  'matches "\b\n{" which cannot be hidden, can use if count is not output, else count incorrect
        Dim searchString = "{:b+\n:b*\{}|{:b*\n:b+\{}"

        DTE.Find.FindWhat = searchString
        DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument  'search current file only
        DTE.Find.Action = vsFindAction.vsFindActionFind
        DTE.Find.MatchInHiddenText = True
        DTE.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr  'regex search
        DTE.SuppressUI = False

        DTE.ActiveDocument.Selection.StartOfDocument()  'set cursor top of file
        While DTE.Find.Execute() <> vsFindResult.vsFindResultNotFound
            count += 1
            DTE.ActiveDocument.Selection.CharLeft(True, 1)  'unselect brace char
            DTE.ExecuteCommand("Edit.HideSelection")
        End While
        DTE.ActiveDocument.Selection.StartOfDocument()

        output += "date: " + Date.Now + vbCrLf
        output += "file: " + DTE.ActiveDocument.FullName + vbCrLf
        output += "count: " + Str(count)
        Out(output)
    End Sub

    Private Function GetOpenFiles() As List(Of EnvDTE.Document)
        Dim openFiles As New List(Of EnvDTE.Document)

        For Each doc As EnvDTE.Document In DTE.Documents
            If doc.ProjectItem IsNot Nothing Then  'todo: combine 
                If doc.ProjectItem.IsOpen() Then
                    openFiles.Add(doc)
                End If
            End If
        Next

        Return openFiles
    End Function

    Private Sub Out(ByVal output)
        GetMacrosOutputWindow().OutputString(output)
    End Sub

    'requires Microsoft Samples Utilities module,
    'copy module into MyMacros project
    Private Function GetMacrosOutputWindow() As OutputWindowPane
        Dim windowTitle = "Expression Software Macros"
        Dim window As Window
        Dim target As Object
        Dim document As EnvDTE.Document

        window = DTE.Windows.Item(Constants.vsWindowKindCommandWindow)
        If DTE.ActiveWindow Is window Then
            target = window.Object
        Else
            target = Utilities.GetOutputWindowPane(windowTitle)
            target.clear()
        End If

        Return target
    End Function
End Module


Public Class EnvDteDocumentComparerClass
    Implements IComparer(Of EnvDTE.Document)

    'compare docs by full filename, for sorting
    Function Compare(ByVal file1 As EnvDTE.Document, _
                     ByVal file2 As EnvDTE.Document) _
                     As Integer Implements IComparer(Of EnvDTE.Document).Compare

        Return file1.FullName.CompareTo(file2.FullName)
    End Function
End Class


Public Class EnvDteDocumentComparableClass
    Implements IComparable(Of EnvDTE.Document)

    'compare docs by full filename, for sorting
    Function CompareTo(ByVal other As EnvDTE.Document) _
                       As Integer Implements IComparable(Of EnvDTE.Document).CompareTo

        Return FullName.CompareTo(other.FullName)
    End Function
End Class


'**************************************************************
'Misc
'DTE.Documents.Count includes closed docs
'DTE.ActiveDocument.FullName
'output += "date: " + Date.Now + vbCrLf
'Microsoft.VisualBasic.Constants.vbCrLf
'DTE.Find.Target = vsFindTarget.vsFindTargetCurrentDocument
'keyboard shortcuts
'  alt + F8    macro explorer
'  alt + F11   macros ide
'**************************************************************

Sunday, March 20, 2011

View Product - Online Catalog Example using ASP.NET MVC 3

View Product URL: http://mvc.expressionsoftware.com/products/1000

Route
routes.MapRoute("view product",
                "products/{id}",
                new { controller = "Product",
                      action = "ViewProduct" });

Controller: \controllers\productController.cs
[HttpGet]
public ActionResult ViewProduct(int id)
{
    var product = Cache.GetProduct(id);
    return View(product);
}

Product Model Class & Object
namespace ExpressionSoftware.Model
{
   public class Product
   {
     public int Id { get; set; }
     public string Name { get; set; }
     public string Description { get; set; }

     public decimal Price { get; set; }
     public string Status { get; set; }
     public bool InStock { get; set; }
     public int StockCount { get; set; }

     public Dictionary<string, string> Metadata { get; set; }
   }
}

new Product() {
                Id = 1000,
                Name = "Foo",
                Description = "Some Foo...",
  
                Price=999.99m,
                Status = "In Stock",
                InStock = true,
                StockCount = 10,
  
                Metadata = new Dictionary<string, string>()
                {
                  { "Color", "Blue"},
                  { "Size", "30 x 16"},
                  { "Manufacturer", "Foo Makers Inc, USA"},
                }

              },

View: \views\product\viewProduct.cshtml
@model ExpressionSoftware.Model.Product
@{Layout = null;}

<!doctype html>
<html>
<head>
  <title>@Model.Name - Products</title>
  <link href="../../ux/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <h1>@Model.Name</h1>
  Id: @Model.Id<br />
  Description: @Model.Description<br /><br />

  Status: @{  //************************************
              if (@Model.InStock) {
                <span class="instock">@Model.Status</span><br />
                @:Count Available: @Model.StockCount
              }
              else {
                @Model.Status
              }
          }<br />

   Price: $@Model.Price<br /><br />
   
   @{  //************************************
       //metadata
       if (Model.Metadata != null) {
         foreach (var kvp in Model.Metadata) {
           @string.Format("{0}: {1}", kvp.Key, kvp.Value);<br />
         }
       }
   }<br />

   @{  //************************************
       <!-- wip - add to cart form / post action -->
       if (@Model.InStock) {
         <input type="submit" value="Add to Cart" />
       }
   }
</body>
</html>

Output HTML
<!doctype html>
<html>
<head>
  <title>Foo - Products</title>
  <link href="../../ux/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <h1>Foo</h1>
  
  Id: 1000<br />
  Description: Some Foo...<br /><br />

  Status: <span class="instock">In Stock</span><br />
  Count Available: 10<br />
  Price: $999.99<br /><br />

  Color: Blue<br />
  Size: 30 x 16<br />
  Manufacturer: Foo Makers Inc, USA<br /><br />
  
  <!-- wip - add to cart form / post action -->
  <input type="submit" value="Add to Cart" />
</body>
</html>



Wednesday, March 2, 2011

Integrating reCAPTCHA with ASP.NET MVC 3

Example using reCAPTCHA in an email-contact page.

www.google.com/recaptcha
code.google.com/apis/recaptcha
www.google.com/recaptcha/api/verify


RecaptchaController Class



\controllers\recaptcha\recaptchaController.cs
using System.Web.Mvc;

namespace ExpressionSoftware.Controllers
{
    public class RecaptchaController : Controller
    {
        //********************************************************
        // PRIVATE DATA - DO NOT HARDCODE
        
           const string RECAPTCHA_PRIVATE_KEY = "----------";
           const string EMAIL_ADDRESS = "john@email.com";
        
        //********************************************************

        const string RECAPTCHA_VERIFY_URL = "http://www.google.com/recaptcha/api/verify";
        
        [AcceptVerbs(HttpVerbs.Get)]
        public ViewResult Default()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public string Default(FormCollection formValues)
        {
            string result = "fail";
            
            //do not submit recaptcha if form vars are null/empty
            if (!(string.IsNullOrEmpty(formValues["recaptcha_challenge_field"]) ||
                  string.IsNullOrEmpty(formValues["recaptcha_response_field"])))
            {
                //alt - validate using web service
                var recaptcha = new ExpressionSoftware.Recaptcha() { PrivateKey = RECAPTCHA_PRIVATE_KEY,
                                                                     VerifyUrl = RECAPTCHA_VERIFY_URL };

                if (recaptcha.Validate(Request.UserHostAddress, formValues["recaptcha_challenge_field"], 
                                                                formValues["recaptcha_response_field"]))
                {
                    result = EMAIL_ADDRESS;  //captcha test passed, show email address
                }
            }
            return result;
        }
    }
}

\views\recaptcha\default.cshtml
<h2>reCAPTCHA Demo for ASP.NET MVC 3</h2>

@using (Html.BeginForm()) {
<input id="b1" type="button" value="Show CAPTCHA" />
<a id="email" />
<div id="captchaDiv"></div>
<input id="submit" type="submit" value="Submit" style="display:none;"/>
<label id="error" style="display:none;">Invalid input, please try again.</label>    
}

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js" type="text/javascript"></script>
<script src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js" type="text/javascript"></script>
<script src="/js/recaptcha.js" type="text/javascript"></script>

\js\recaptcha.js
$(document).ready(function() {
  $("form").submit(
    function(event) {
      event.preventDefault();
      submit(this, updateUI, "html");
    });
  $("#b1").click(showCaptcha);
});

function submit(form, callback, format) {
  $.ajax({url: form.action,
          type: form.method,
          dataType: format,
          data: $(form).serialize(),
          success: callback
         });
}

function updateUI(result) {
  result = $.trim(result);
  
  if (result == "fail") {
    $("#error").show();
    Recaptcha.reload();
    Recaptcha.focus_response_field();
  }
  else {  //success
    $("#email").text(result);
    $("#email")[0].href = "mailto:"+result;
    $("#captchaDiv").hide();
    $("#submit").hide();
    $("#error").hide();
  }
}

function showCaptcha() {
  Recaptcha.create("6LdXGMISAAAAAKbqYwaabU7h1qjwGYEXoEelZjWV",  //api public key
                   "captchaDiv",
                   {
                     theme: "clean",
                     callback: Recaptcha.focus_response_field
                   }
                  );
  $("#b1").hide();
  $("#submit").show();
  return false;
}


Recaptcha Class / Web Service



recaptcha.cs
using System.IO;
using System.Net;
using System.Text;

namespace ExpressionSoftware
{
    public class Recaptcha
    {
        public string VerifyUrl { get; set; }
        public string PrivateKey { get; set; }

        public bool Validate(string remoteIP, string captchaChallenge, string captchaResponse)
        {
            bool result = false;
            string response = GetWebResponse(remoteIP, captchaChallenge, captchaResponse);
            result = response.ToLower().StartsWith("true");  //api response line 1 value: true or false
            return result;
        }

        string GetWebResponse(string remoteIP, string captchaChallenge, string captchaResponse)
        {
            string result = null;

            //convert params to byte array
            var parameters = string.Format("privatekey={0}&remoteip={1}&challenge={2}&response={3}",
                                           PrivateKey, remoteIP, captchaChallenge, captchaResponse);
            byte[] paramData = Encoding.UTF8.GetBytes(parameters);

            var request = (HttpWebRequest)WebRequest.Create(VerifyUrl);
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = paramData.Length;
            request.ServicePoint.Expect100Continue = false;
            
            //write param data to request stream
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(paramData, 0, paramData.Length);
                requestStream.Close();
            }

            using (WebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream stream = response.GetResponseStream())
                {
                    using (StreamReader responseReader = new StreamReader(stream))
                    {
                        result = responseReader.ReadToEnd();
                        responseReader.Close();
                    }
                    stream.Close();
                }
                response.Close();
            }
            return result;
        }
    }
}



Blog Archive