How I survived “S.M.A.R.T. Status: BAD. Backup and Replace”

June 12, 2012

My Windows 7 started to display the “Windows detected a hard disk problem” error message. While I first ignored it, I finally ran chkdsk /f /r on all disks just to make sure erroneous sectors would not cause the error to show again.

Unfortunately, this did not work out, and the error message became more persistent.

A look into the event log presented more and more warnings (Event ID 52, Source Disk)

The driver has detected that device <device> has predicted that it will fail. Immediately back up your data and replace your hard disk drive. A failure may be imminent.

and errors (Event ID 7, Source Disk)

The device, <device>, has a bad block.

(The Events and Errors Message Center does not even know these event IDs exist.)

Restarting the PC would stop the boot process with the message

S.M.A.R.T. Status: BAD. Backup and Replace
Press F1 to continue

I decided to finally bring myself to fix the situation, and asked teh internets how to do it. (I already fixed a dying drive once, but that was Ubuntu, and this is Windows, and it can get ugly.

The dying disk is a Seagate, so I tried the SeaTools (both Windows and DOS) because they might help resolve the errors, but they didn’t.

Fortunately, the new disk is also a Seagate, a different model but the same size as the old one, so I downloaded Seagate DiscWizard on my laptop to create a bootable CD. Unfortunately, DiscWizard setup requires Seagate disks installed in the PC, which the laptop does not have. Back to square one.

In the end, I mounted the new disk in the PC, installed DiscWizard, and started it. The selection of source and destination disks cause adrenaline levels to jump, but the selection dialog (of both disks) always displays the partitions of each selected disk, so the the likelihood of selecting both drives wrong due to poor UI is greatly reduced (see screenshots in the HowTo).

After disk copying completed, I disconnected the old disk and left the new disk connected on the same cable as during copying, booted, and, voilà, logged into my old new Windows 7.


Using ABCpdf in a Windows Service

April 16, 2012

One of my long-term projects is a web application which can generate PDF documents on the fly, but bigger PDFs can also be generated offline using a Windows service. Both the web application and the service use the same code base to invoke the ABCpdf library.

Recently, an update of Server 2008 to IE9 forced me to switch to ABCpdf’s Gecko engine, and this switch caused the service, which runs under the Local System account, to fail unexpectedly.

The Event Log contained various error entries:

Source ABCpdf

The following information was included with the event:
Failed to add HTML: Page load timed out.

Source Application Error

Faulting application MyService.exe, version 1.0.0.0, time stamp 0x4f883a56,
faulting module KERNEL32.dll, version 6.0.6002.18005, time stamp 0x49e037dd,
exception code 0xe0434f4d, fault offset 0x0003fbae, process id 0x%9, application start time 0x%10.

Source ASP.Net 2.0.50727.0

An unhandled exception occurred and the process was terminated.

After adding some logging, the following exceptions were reported

Exception: System.Runtime.Serialization.SerializationException

Message: Type ‘WebSupergoo.ABCpdf8.Internal.Spawntaneous.SpawntaneousException’ in Assembly ‘ABCpdf, Version=8.1.0.1, Culture=neutral, PublicKeyToken=a7a0b3f5184f2169′ is not marked as serializable.

StackTrace:    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeObject(Object obj, MemoryStream stm)
at System.AppDomain.Serialize(Object o)
at System.AppDomain.MarshalObject(Object o)

WebSupergoo.ABCpdf8.Internal.PDFException: Failed to add HTML: Page load timed out.

   at WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback.MyCallback(IntPtr closure, IntPtr serializedOpts, UInt32 serializedOptsLen, Double widthInMm, Double heightInMm, String url, UInt32& outNumCommands, IntPtr& outSerializedData, UInt32& outSerializedDataLen)
at WebSupergoo.ABCpdf8.Internal.NDoc.N.AddImageUrlGecko_32(IntPtr doc, String url, Int32 width, IntPtr callback, String& outErr)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddUrl(Doc doc, String url, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddHtml(Doc doc, String html, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html)

System.TypeInitializationException: The type initializer for ‘WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback’ threw an exception. —> WebSupergoo.ABCpdf8.Internal.Spawntaneous.SpawntaneousException: Failed to generate worker process.

   at WebSupergoo.ABCpdf8.Internal.Spawntaneous.ProcessGenerator.GenerateLocalInvoker(MethodInfo method, String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Spawntaneous.WorkerProcessExe.Init(String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Spawntaneous.WorkerProcessExe..ctor(String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback..cctor()
— End of inner exception stack trace —
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddUrl(Doc doc, String url, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddHtml(Doc doc, String html, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html)

As you can see, the last two exceptions were caused by calling AddImageHtml(), which is the entry point to the invocation of the Gecko rendering engine, therefore my reasoning was that the Gecko engine required something that the MSHTML rendering engine did not need.

I remembered that on IIS, the AppPool’s “Load User Profile” needs to be set, so probably it had something to do with the service running as Local System which does not have a user profile?

As it turns out, setting the service to run under a local user in Control Panel/Administration/Services fixed the problem, and the service was again able to generate PDF files.


Windows Update killed my ABCpdf

April 2, 2012

An application I develop (dev environment: Win7 Pro, IE9, ASP.Net 3.5) suddenly showed problems running on Windows Server 2008: the web application could not create PDF documents anymore, and

  • The browser only displayed a “Service Unavailable” message
  • The browser user was automatically logged out of the web application
  • The web request did not show in the IIS log
  • No error in the Application events

A process serving application pool ‘MyAppPool’ suffered a fatal communication error with the Windows Process Activation Service. The process id was ’2688′. The data field contains the error number.

The details tab displayed the following information:

ProcessID 2688
6D000780

Binary data:

In Words

0000: 8007006D

In Bytes

0000: 6D 00 07 80

Teh Internets wanted me to debug IIS and my .Net application with IIS Diagnostics Toolkit, and Debug Diagnostic Tool, and IISState, and awe-inspiring how-to instructions.

Instead, I chose to add logging statements to the code that was affected by the error, and found that cause to be the statement

int theID = doc.AddImageHtml(html);

As it turns out (thank you SO, also here), you need to activate the Gecko engine in ABCpdf to work on (some) IE9 machines (as I said, the code works ok on Win7Pro, and I had recently updated the server):

doc.HtmlOptions.Engine = EngineType.Gecko;

Trying out the Gecko engine, the next result I got was

WebSupergoo.ABCpdf8.Internal.PDFException: ABCpdf cannot detect any printers. Gecko Engine requires a printer installed in the system. Usually, XPS Document Writer would suffice. Try also running the service as an interactive user. —> System.ComponentModel.Win32Exception: The RPC server is unavailable
at System.Drawing.Printing.PrinterSettings.get_InstalledPrinters()
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.get_DefaultPrinter()
— End of inner exception stack trace —
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.get_DefaultPrinter()
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.Preflight(Doc doc)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddHtml(Doc doc, String html, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html)

After creating an XPS printer in control panel, the web application was finally able to generate PDF documents again.

According to the ABCpdf support page (6.29), the MSHTML rendering engine should be avoided for future applications:

Unfortunately with the official release of IE9 Microsoft released new documentation which says the IHTMLElementRender::DrawToDC function that was required has been deprecated. This is especially unfortunate given that there is no replacement for this function.

Given that Microsoft appears to be unwilling to support these interfaces we would strongly recommend that on new deployments you consider a move to the new Gecko-based HTML engine available in ABCpdf 8.


Test if Directory exists in Batch file (.cmd)

February 16, 2012

My previous post on testing network drives led me to further research the topic, and I came to quite surprising (at least for me) results: the result if a check with IF EXIST depend on whether

  • the drive is a local drive or a mapped network drive or a UNC path
  • the path contains spaces or not
  • the path is quoted or not
  • cmd runs in administrator mode or user mode

I wrote a small batch file that contains a couple of assignments of the form

set dir=c:\temp
set dir=c:\temp\with spaces
etc.

and executed these tests on each value

if exist %dir% echo exists
if exist %dir%\nul echo exists
if exist %dir%\. echo exists
if exist "%dir%" echo exists
if exist "%dir%\nul" echo exists
if exist "%dir%\." echo exists

These are the results

directory %dir% %dir%\nul %dir\. “%dir%” “%dir%\nul” “%dir%\.”
local x x x x x
local (spaces) - - - x x
mapped (non-admin) x x x x x
mapped (non-admin, spaces) - - - x x
UNC x x x x x x
UNC (spaces) - - - x x x

Comments:

Testing directory path containing spaces can only be performed using the quoted notation.

Mapped network drives can only be access in non-administrator mode (see these threads).

The only reliable way to test for directory existence is therefore to use the quoted “%dir%\.” notation.

To check whether cmd runs in administrator mode or not, use an admin statement such as ‘at’:

at >nul 2>nul
if errorlevel 1 echo you are not in administrator mode

Test if Network Directory exists in Batch file (.cmd)

February 16, 2012

The default way to check whether a directory exists in a Windows batch file (.cmd) is

if not exist "%directory%\nul" (
   echo %directory% does not exist
)

However, as this MS KB explains, the check for the NUL file does not work with directories on network drives mapped to a drive letter.

A working solution I found is to process the ERRORLEVEL value a DIR command sets

dir %directory% >nul 2>nul
if errorlevel 1 (
   echo %directory does not exist
)

or

dir %directory% >nul 2>nul
if not errorlevel 1 (
    echo %directory exists
)

Also note that mapped network drives are not available in administrator mode, as is discussed in these threads.


New (empty) Window in IE9

January 25, 2012

If you press Ctrl-N in Internet Explorer (e.g. IE9), it opens a new window with the same web page. So how do you open a new empty window?

This thread lists 3 methods to open a new IE window from the taskbar:

  • Right-click an IE icon, and select “Internet Explorer”
  • Shift + Left-click on an IE icon
  • Middle-click on an IE icon

Of course, you can also select Internet Explorer from the Program Menu to get a new window.


xcopy to c:\inetpub\wwwroot fails with “Access denied”

January 25, 2012

Rather than manually copying files from \\tsclient\some\path to c:\inetpub\wwwroot\webdir I wanted to write a small batch file using xcopy and /exclude to deploy web application files.

However, even when starting the .cmd from a command line in administrator mode, I received an “Access denied” message for each file to be copied due to User Account Control prohibiting write access.

As it turns out, the task can be successfully performed using robocopy with the /zb (or /b ?) switch. (Use robocopy /? to find the huge collection of switches.)

Consequently, the feature known as xcopy deployment should therefore be renamed to robocopy deployment ;)


Extracting .msi Files without Installation

September 19, 2011

Occasionally you need to access the contents of an .msi file, but you are sitting on a PC where you do not administrative rights to run the installer.

I noticed 7-Zip adds itself to the context menu of .msi files, but it extracts the whole contents of the msi, and the output is somewhat confusing to me (admittedly, I do not use the latest version of 7-Zip).

Fortunately I came across lessmsi which opens an .msi file, allows you to select the desired files, and extracts them into the file’s sub-directory as found in the Directory column of each of the contained files.

Simple and effective!


cmd.net: uniq

June 27, 2011

Finally the command that prompted the creation of cmd.net in the first place: uniq.

Before implementing the command, I had to find out which options the default Linux implementations provided.

I used these pages as guideline:

The resulting command filters unique lines from stdin (or a piped input file) to stdout, and supports these options:

uniq [parameters]

displays unique lines in sorted file

-u      unique lines only
-d      repeated lines only
-c      display line count
-i      ignore case
-f      [ignore fields]         ignore number of fields
-s      [skip characters]       skip number of characters
-w      [compare characters]    compare number of characters
-in     [encoding]      input encoding
-ci     [culture]       culture info
-out    [encoding]      output encoding

uniq 0.10.4117.37457
cmd.net 0.10.0.0 (c) by devio.at 2011

Note that uniq only analyzes subsequent lines of text in the file. Thus it only operates correctly on a pre-sorted file. If the input is not sorted, equal lines may be output more than once (but not subsequently).

The first version of cmd.net is available for download here, and contains the commands described in this post.


cmd.net: tee, xslt

April 18, 2011

The tee command of the cmd.net collection is a .Net implementation of the tee command available on other platforms.

As usual, the -in and -out switches define the encodings of stdin and stdout.

The filename parameter is given directly (without a leading switch), and the file’s encoding can be defined using the -enc switch.

The -a switch appends to an existing file instead of creating a new file.

The xslt command is a translation of the PowerShell xslt script I posted some time ago.

The xml file is provided on stdin, and the xslt file is defined via the -xslt switch (along with -xsltenc for the encoding).

Again, the -in and -out switches define the encodings of stdin and stdout.

The current version of cmd.net is available for download here.


Follow

Get every new post delivered to your Inbox.