Friday, January 28, 2011

Getting the current page URI in classic ASP

This JScript gets the current URI in a classic ASP server page:

function getSv(name) { return Request.ServerVariables(name) }
var currentUri = ((getSv("HTTPS") == "off") ? "http" : "https") + "://" + getSv("SERVER_NAME") + getSv("SCRIPT_NAME")

Thursday, January 27, 2011

Logging to Windows Event Log using JScript

This handy function allows you to log to the Windows Event Log using JScript, for example from a classic ASP web page:

function Log(message) {
    var shell = new ActiveXObject("WScript.Shell")
    shell.Exec('eventcreate /id 1 /l [LOG] /SO [SOURCE] /T ERROR /D "' + String(message).replace('"', '""') + '"')
}

Tuesday, January 25, 2011

Killing all processes that have a DLL loaded

To kill all the tasks or processes that have a DLL loaded or open, use taskkill.exe:

PS C:\> taskkill.exe /im * /t /f /fi "modules eq [YOURMODULENAME.DLL]"
SUCCESS: The process with PID 7664 (child process of PID 2572) has been terminated.

Saving the output of a windows batch file (.cmd file) to a file

Sometimes it is useful to save the output of a Windows batch file to a file as well as display it to the screen. This is a possible solution:

@echo off
setlocal
set logfile=Log.log
if not "%1" == "/nolog" (
  (
    date /t & time /t
    call %0 /nolog
  ) >> %logfile% 2>&1
  type %logfile%
  endlocal
  exit /b
) 

... your batch file starts here...

It is much easier to achieve this in a PowerShell script by using the Start-Transcript cmdlet. Tee-Object may also be handy, because it can display the output onto the screen as well as writing to a file.

Sunday, January 23, 2011

Bulk lossless automatic rotation of photos on Windows

Some cameras 'know' what angle the camera was being held at when the photo was taken, and this information is written to the image's EXIF data. It is possible to rotate images with this information so that they are correctly oriented.

  1. Download jhead and jpegtran into the same folder (preferably on the path).
  2. Run jhead -autorot *.jpg

Saturday, January 15, 2011

Diagnosing slow Windows 7 boot times

To see what your machine is doing during boot up, use the tool xperfboot.exe from the Windows SDK or as a download from the Windows Performance Analysis Developer Centre.

Run this command:

xbootmgr –trace rebootCycle -resultPath %temp%\boot

This will reboot your machine twice.

xperfview can then be used to view the output:

xperfview %temp%\boot\boot_BASE+CSWITCH_1.etl

Friday, January 14, 2011

The Hamachi server has denied your login request

I ran into this problem after upgrading an older version of Hamachi:

The Hamachi server has denied your login request.



Simple Solution

This page is very popular, so I wrote an application that will reset the Hamachi configuration. The application is the simplest solution, but the steps below do the same job. Download the application here (source is on BitBucket).

You may need to restart your computer after running this program. Please let me know in the comments below whether the application fixes your problem.It looks like this program does not work on all operating systems and fix this error for all people. Your mileage may vary - feel free to contribute to the source code with your own situation.




The way I solved this problem was to delete the Hamachi configuration files. Procmon was able to locate the configuration folders:
  • Depending on your system, one of:
    %WinDir%\System32\Config\SystemProfile\AppData\Local\LogMeIn Hamachi
    %USERPROFILE%\..\LocalService\Local Settings\Application Data\LogMeIn Hamachi
  • And:
    %USERPROFILE%\Local Settings\Application Data\LogMeIn Hamachi
Below are steps you could use to clear the corrupted configuration on Windows.
  1. Start an elevated command prompt. In Windows 7 and Vista, press the Windows key or click on the Start menu, then type cmd into the text field at the bottom of the Start menu. Right click on the cmd icon at the top of the Start menu and click Run as administrator - you will need to either enter an administrator password or accept the dialog that pops up next. If you do this correctly, a black window called the command prompt will pop up.
  2. Copy this command line. Double click the command below to select it, and then press Ctrl+C or right click and select Copy to copy the command into the clipboard of your computer.
    cmd /c rd /s/q "%USERPROFILE%\..\LocalService\Local Settings\Application Data\LogMeIn Hamachi" & rd /s/q "%USERPROFILE%\Local Settings\Application Data\LogMeIn Hamachi" & rd /s/q "%WinDir%\System32\Config\SystemProfile\AppData\Local\LogMeIn Hamachi"
  3. Run the command line. Paste the command into the black window and hit enter to run it. It should reset your Hamachi configuration files and fix the problem.

Please let me know by commenting below if this works or not for your particular situation, along with the version of Hamachi you are running if you know it.

Saturday, January 8, 2011

Trinity Rescue Kit (TRK) 3.4 does not resolve DNS out of the box

If you boot the Trinity Rescue Kit (TRK) 3.4 build 367 and try to run a tool that requires the internet, such as a virus scan, you may get an error like this:

Neither DNS nor proxy parameters for wget found so no internet connection, cannot fetch AV engine

Attempting to ping google.com from a shell returns this error:
ping: unknown host google.com

The solution seems to be to launch dhcpcd from the command line:

Setting up my PXE boot server

This is basically a summary for my own records of my PXE boot configuration in case I want to rebuild it. It is quite specific to the distributions I want to access via PXE and to my configuration, so other guides will probably be more useful for readers.

Structure:
.
|-- debian
|   `-- testing
|       `-- amd64
|           |-- initrd.gz
|           `-- linux
|-- menu.c32
|-- pxelinux.0
|-- pxelinux.cfg
|   |-- default
|   `-- trinity
`-- trinity
    |-- ...lots of files...

With files sourced from:

The folder structure is mounted (or directly in) /var/lib/tftpboot, and it is exported using NFS (for TRK) by the following configuration line in /etc/exports:

/var/lib/tftpboot/trinity *(ro,no_root_squash,no_subtree_check)

The folder structure is also exposed using tftpd-hpa (not tftpd) and the DHCP server is using Tomato on my router with the following configuration line in Advanced -> DHCP / DNS -> Dnsmasq custom configuration:

dhcp-boot=pxelinux.0,,192.168.1.13

There is some duplication between the two files, but I was happy enough to get them working as I wanted. If I had more time, I would look into MENU INCLUDE.

This is the configuration file called default.
default menu.c32
prompt 0

menu title Welcome to My Network Boot Menu
menu color tabmsg 37;40      #80ffffff #00000000
menu color hotsel 30;47      #40000000 #20ffffff
menu color sel 30;47      #40000000 #20ffffff
menu color scrollbar 30;47      #40000000 #20ffffff

MENU WIDTH 75
MENU MARGIN 5
MENU PASSWORDMARGIN 3
MENU ROWS 18
MENU TABMSGROW 22
MENU CMDLINEROW 22
MENU ENDROW 24
MENU PASSWORDROW 11
MENU TIMEOUTROW 23

label 1
menu label Debian Install
kernel debian/testing/amd64/linux
append vga=normal initrd=debian/testing/amd64/initrd.gz  --

label 2
menu label Debian Expert Install
kernel debian/testing/amd64/linux
append priority=low vga=normal initrd=debian/testing/amd64/initrd.gz  --

label 3
menu label Debian Rescue
kernel debian/testing/amd64/linux
append vga=normal initrd=debian/testing/amd64/initrd.gz rescue/enable=true --

label 4
menu label Trinity
kernel menu.c32
append pxelinux.cfg/trinity

The following configuration file was generated by trk3/mkpxelinux in the TRK, but I modified it to find kernel.trk and initrd.trk in the trinity sub-folder, then renamed it to trinity:

VIM commands:
:%s/kernel\.trk/trinity\/kernel.trk/g
:%s/initrd\.trk/trinity\/initrd.trk/g
:%s/vesamenu\.c32/menu.c32/g

This is the configuration file called trinity.
default menu.c32
prompt 0

menu title     build 367
menu color tabmsg 37;40      #80ffffff #00000000
menu color hotsel 30;47      #40000000 #20ffffff
menu color sel 30;47      #40000000 #20ffffff
menu color scrollbar 30;47      #40000000 #20ffffff

MENU WIDTH 75
MENU MARGIN 5
MENU PASSWORDMARGIN 3
MENU ROWS 18
MENU TABMSGROW 22
MENU CMDLINEROW 22
MENU ENDROW 24
MENU PASSWORDROW 11
MENU TIMEOUTROW 23


label trk3
menu label  Run ^Trinity Rescue Kit 3.4 (default mode, with text menu)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp  splash=verbose pci=conf1 trkmenu
timeout 100

label 1
menu label ^1 : TRK 3.4 in failsafe mode (No menu, VGA, noacpi, noapic)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose acpi=off noapic pci=conf1 vga=1

label 2
menu label ^2 : TRK 3.4 running from RAM (best >= 512mb, 256mb min)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 trkinmem trkmenu

label 3
menu label ^3 : TRK 3.4 - Run 'mclone' in client mode (!)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 mclone

label 4
menu label ^4 : TRK 3.4 in simple VGA mode (debugging of kernel output)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=1 pci=conf1 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=off trkmenu

label 5
kernel trinity/kernel.trk
menu label ^5 : TRK 3.4 with Belgian keyboard (use menu for other)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 keyb_be trkmenu

label 6
kernel trinity/kernel.trk
menu label ^6 : TRK 3.4 - Virusscan all drives (Clamav, non interactive)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 virusscan

label 7
kernel trinity/kernel.trk
menu label ^7 : TRK 3.4 - Try more pcmcia and usb nics (when not detected)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 pcmcia trkmenu

label 8
kernel trinity/kernel.trk
menu label ^8 : TRK 3.4 - Try more SCSI drivers (when disks not detected)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 scsidrv trkmenu

label 9
kernel trinity/kernel.trk
menu label ^9 : TRK 3.4 with a secure shell server enabled
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 sshd

label 10
kernel trinity/kernel.trk
menu label 10: TRK 3.4 - E^xecute local scripts on harddrive of PC
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 locscr

label 11
menu label 11: TRK 3.4 as bootserve^r to boot other TRK clients
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 trkbootnet trkmenu

label 12
kernel trinity/kernel.trk
menu label 12: TRK 3.4 - Fileshare all drives as ^guest, no security
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 smbguest trkmenu

label 0
kernel trinity/kernel.trk
menu label 13: TRK 3.4 - ^Single user mode (no menu)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 runlevel 1

label noacpi
kernel trinity/kernel.trk
menu label 14: TRK 3.4 - Acpi=off, noapic  PCI=^bios (Alternate boot 1)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose acpi=off noapic pci=bios trkmenu

label pcinormal
kernel trinity/kernel.trk
menu label 15: TRK 3.4 - ^Acpi=off, noapic PCI=any (Alternate boot 2)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose acpi=off noapic trkmenu

label pciconf1
kernel trinity/kernel.trk
menu label 16: TRK 3.4 - ^PCI=conf2 (Alternate boot 3)
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf2 trkmenu

label debug
menu label 17: TRK 3.4 - ^Verbose startup for debugging (no menu)
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 debugging

label 18
menu label 18: TRK 3.4 - SSH, boot- and guest ^fileserver, run from RAM
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 sshd trkinmem smbguest trkbootnet trkmenu

label 19
menu label 19: TRK 3.4 - Run from RAM, run m^clone as client
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 trkinmem mclone

label 20
menu label 20: TRK 3.4 with prox^yserver support enabled
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 proxy trkmenu

label 21
menu label 21: TRK 3.4 - All devices set to read-only
kernel trinity/kernel.trk
append initrd=trinity/initrd.trk ramdisk_size=65536 root=/dev/ram0 vga=788 trknfs=192.168.1.13:/var/lib/tftpboot/trinity ip=::::::dhcp splash=verbose pci=conf1 allro

label t
menu label 22: ^Memory tester: Memtest86+ v1.65
kernel memtest.x86

Problem PXE booting Trinity Rescue Kit (TRK) 3.4

After reconfiguring my PXE boot system to boot the Trinity rescue kit, partly by following the official guide, I ran into the following error:

Looks like we 're booting from network, mounting xxxx:/yyy on /trk
/trk/trk3/trkramfs: Permission denied
Something's wrong in startup, dropping to a shell, stop booting

The solution is to modify the permissions on the file trkramfs:

chmod +rx trkramfs

I am not sure why this problem would occur in the latest build.

I was using the Trinity Rescue Kit 3.4 build 367.

Friday, January 7, 2011

Keeping track of system freezes with PowerShell

A colleague has been having some problems with her Windows 7 x64 machines freezing and requiring a forced shut-down. Unfortunately, these are not logged in the reliability monitor, but they are logged in the event log. I used PowerShell to process the event log to find start-up and shut-down events:

#Based on information from http://support.microsoft.com/kb/196452

$results = @()

function GetResult($time, $message)
{
    return New-Object psobject -Property @{ Time = $time; Message = $message };
}

Get-EventLog System | ? { $_.Source -eq "EventLog" -and 6006,6008,6009 -contains $_.EventId } | % {
    $item = $_
    switch($_.EventID)
    {
        6006 { $results += (GetResult $item.TimeGenerated "Clean shutdown") }
        6008 
        { 
            if(-not ($item.Message -match "^The previous system shutdown at (.*) on (.*) was unexpected.$"))
            {
                throw "Invalid format."
            }
            $c = ($matches[2] -replace '\u200E','') + " " + ($matches[1] -replace '\u200E','');  #not sure why, but it includes the unicode character 'LEFT-TO-RIGHT MARK'
            $dt = [datetime]::parse($c)
            $results += (GetResult $dt "Dirty shutdown")
        }
        6009 { $results += (GetResult $item.TimeGenerated "Start-up") }
    }
}

$results | sort Time -Descending

Running the script will create output similar to this:
.\ShutdownEvent.ps1

Message        Time
-------        ----
Start-up       7/01/2011 13:34:38
Dirty shutdown 7/01/2011 13:18:22
Start-up       7/01/2011 08:18:25
Clean shutdown 6/01/2011 16:44:41
Start-up       6/01/2011 08:19:52
Clean shutdown 5/01/2011 16:42:38
Start-up       5/01/2011 08:18:23
Clean shutdown 31/12/2010 16:21:51
Start-up       31/12/2010 08:50:07
Clean shutdown 30/12/2010 16:36:55
Start-up       30/12/2010 08:49:39
Clean shutdown 29/12/2010 16:37:34
Start-up       29/12/2010 08:50:48
Clean shutdown 24/12/2010 09:52:04
Start-up       24/12/2010 08:46:15
Clean shutdown 23/12/2010 13:25:19
Start-up       23/12/2010 08:02:46
Clean shutdown 22/12/2010 16:37:40
Start-up       22/12/2010 08:02:18
Clean shutdown 21/12/2010 16:35:55
Start-up       21/12/2010 08:02:13
Clean shutdown 20/12/2010 16:32:50
Start-up       20/12/2010 08:01:52


You can also filter the output, for example to only show dirty shut-down events:

.\ShutdownEvent.ps1 | ? { $_.Message -match 'Dirty.*' }

Message        Time
-------        ----
Dirty shutdown 7/01/2011 13:18:22
Dirty shutdown 16/09/2010 08:23:41
Dirty shutdown 9/09/2010 11:04:31
Dirty shutdown 19/07/2010 11:35:27
Dirty shutdown 14/07/2010 13:52:24
Dirty shutdown 8/07/2010 13:40:26
Dirty shutdown 7/05/2010 08:22:57

Thursday, January 6, 2011

Capturing both output and error streams from a .NET process

MSDN documents a well-known problem that needs to be worked around when reading output from a console process started using System.Diagnostics.Process:

The code example avoids a deadlock condition by calling p.StandardOutput.ReadToEnd before p.WaitForExit. A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd and the child process writes enough text to fill the redirected stream. The parent process would wait indefinitely for the child process to exit. The child process would wait indefinitely for the parent to read from the full StandardOutput stream.

The example in MSDN is:

// Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "Write500Lines.exe";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

The problem with this example is that it only reads from stdout - not from stderr. One solution, using the new .NET TPL (Task Parallel Library), is to launch two tasks that read the output and error streams.

ProcessStartInfo psInfo = new ProcessStartInfo
{
    Arguments = @"/c dir C:\",
    FileName = @"C:\Windows\system32\cmd.exe",
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    UseShellExecute = false
};

Process proc = Process.Start(psInfo);
string stderr = null, stdin = null;
Parallel.Invoke(() => stdin = proc.StandardOutput.ReadToEnd(),
    () => stderr = proc.StandardError.ReadToEnd());
proc.WaitForExit();

There is one caveat with this approach - Parallel.Invoke does not seem to guarantee that both tasks will run in parallel. I will need to investigate this some more.

Wednesday, January 5, 2011

Booting into the MBR of another drive using GRUB 2

I wanted to try dual booting Linux and Windows on my machine, whose existing Windows hard drive is fully encrypted with Truecrypt. To avoid complications with Truecrypt, I put another physical disk in the machine with the intention of installing Linux on that. I wanted to be sure that the install did not touch the Truecrypt disk, including the MBR on that disk. The intention is that the new disk will become the boot disk and it will either load Linux or boot from the MBR on the Truecrypt disk.

The first trick is to make sure that the Linux installer does not overwrite the MBR on the Truecrypt disk, potentially rendering it unbootable. During the "expert install" of Debian based distros (including Ubuntu), it is important to install Grub 2 and then instruct Grub not to install to the MBR of the first hard disk. The installer will then give you the option to specify the drive whose MBR to modify - at this stage, choose the Linux disk, rather than the Trurcrypt disk.

After setting the Linux disk to be the boot disk in BIOS, edit /etc/grub.d/40_custom as the root user and add the following lines to the end:

menuentry "Other Disk" {
    set root = (hd1)
    chainloader +1
}

The key here is to set root to the Truecrypt hard drive. Do not specify a partition, because we want to boot using the MBR of the disk. Booting into grub and using ls at the grub command prompt will give you a list of all the available drives.

After modifying 40_custom, run update-grub, and reboot. You should be able to boot into Linux or into the Truecrypt drive using the Other Disk menu entry.

Tuesday, January 4, 2011

Change index from clustered to nonclustered in SQL Server 2008

  1. Open the database in SQL Server Management Studio.
  2. Right-click on the table that has the clustered index and select Design.
  3. Right click on a blank space on the design view and select Indexes/Keys from the context menu.
  4. Select the index that you want to modify in the list on the left.
  5. Change the value of the property Create As Clustered from Yes to No.
  6. Click close, then save the table design view. 

Monday, January 3, 2011

Using the AJAX minifier as an MSBuild task to compress JavaScript



It is possible to us the AJAX Minifier to generate compact Ecmascript (JavaScript) and CSS files.

Add the following to your .csproj file within the Project tag. This page gives more detail.

<Target Name="AfterBuild">
  <ItemGroup>
    <JS Include="**\*.original.js" />
    <CSS Include="**\*.original.css" />
  </ItemGroup>
  <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.original.js$" JsTargetExtension=".js" 
            CssSourceFiles="@(CSS)" CssSourceExtensionPattern="\.original.css$" CssTargetExtension=".css"
            JsOutputMode="MultipleLines" JsCombineDuplicateLiterals="true"/>
</Target>

The documentation is good except that it does not detail all the options for the MSBuild task. I list them for version 4.0 below, with descriptions copied from various places including the source code and documentation:

OptionEffectDefault
JsCollapseToLiteralCollapse new Array() to [] and new Object() to {}.true
JsCombineDuplicateLiteralsCombine duplicate literals within function scopes to local variables.false
JsEnsureFinalSemicolonAppends a semi-colon to the end of the minified JavaScript.true
JsEvalTreatmentNormally an eval statement can contain anything, including references to local variables and functions. If it is expected to do so, when the tool encounters an eval statement, that scope and all parent scopes cannot take advantage of local variable and function renaming because things could break when the eval is evaluated and the references are looked up. To reduce the amount of resulting minification but make sure that all possible references in evaluated code will hold true, use the MakeAllSafe value. However, sometimes the developer knows that he’s not referencing local variables in his eval (like when only evaluating JSON objects), and this switch can be set to Ignore to make sure you get the maximum reduction in resulting code size. Or alternatively, if the developer knows the code being evaluated will only access local variables and functions in the current scope and nowhere else, the MakeImmediateSafe value can be specified and all parent scopes will still rename their locals. Very dangerous setting; should only be used when you are certain of all possible behavior of evaluated code. Ignore
JsIndentSizeFor the multi-line output feature, how many spaces to use when indenting a block (see OutputMode).4
JsInlineSafeStringsBreak up string literals containing </script> so inline code won't break.true
JsLocalRenamingRenaming of locals. There are a couple settings: KeepAll is the default and doesn’t rename variables or functions at all. CrunchAll renames everything it can. In between there is KeepLocalizationVars, which renames everything it can except for variables starting with L_. Those are left as-is so localization efforts can continue on the minified code.CrunchAll
JsMacSafariQuirksThere are two quirks that Safari on the Mac (not the PC) needed: throw statements always seem to require a terminating semicolon; and if statements that only contains a single function declaration need to surround that function declaration with curly-braces. Basically, if you want your code to always work in Safari, set this to true. If you don’t care about Safari (for instance, in a corporate environment where the browser your users can use is highly restricted), setting this value to false might save a few bytes.true
JsOutputModeSingleLine minifies everything to a single line. MultipleLines breaks the minified code into multiple lines for easier reading (won’t drive you insane trying to debug a single line). The only difference between the two outputs is whitespace. (see also: IndentSize).SingleLine
JsRemoveFunctionExpressionNamestrue
JsRemoveUnneededCodeShould be set to true for maximum minification. Removes unreferenced local functions (not global functions, though), unreferenced function parameters, quotes around object literal field names that won’t be confused with reserved words, and it does some interesting things with switch statements. For instance, if the default case is empty (just a break), it removes it altogether. If there is no default case, it also removes other empty case statements. It also removes break statements after return statements (unreachable code). true
JsStripDebugStatementsremoves “debugger” statements, any calls into certain namespaces like $Debug, Debug, Web.Debug or Msn.Debug. also strips calls to the WAssert function.true