User avatar
kevotheclone
Posts: 245
Joined: Mon Sep 08, 2008 7:16 pm
Location: Elk Grove, California

"Save as MHT" Send to Tool

Post by kevotheclone » Tue Mar 24, 2009 8:16 am

Updated 3/29/2009[b/] with suggestion made by Taka: use the "current" directory to build the path to [b]gmht.exe
This was a 5 minute fix, took 10 minutes to test, and 3 days to find the time to post the update. I'll also added code to determine if gmht.exe exists in Awasu's installation directory before attempting to call it,

As discussed in this thread, http://www.awasu.com/forums/viewtopic.php?t=8336, Awasu's extensibility can make it relatively simple to retrieve the full web page referenced by a feed item and save it as an MHT file. An MHT file is a Microsoft "Web Archive" file format that stores the complete web page in a single file. It's basically a MIME multi-part format (http://en.wikipedia.org/wiki/MIME) similar to richly formatted email messages; all images are base-64 encoded so the file size increases somewhat, but with images embedded within the resultant MHT file, it is a highly portable file format for Windows/Internet Explorer users.

Apparently, the MHT file format is the file format that Awasu uses to store pages for offline reading and Taka was kind enough to share how to call the gmht.exe program to save a web page as an MHT file, so...

I wrote a Send to tool to save the page referenced by a feed item to an MHT file in a directory you specify. It's written in VBScript so it should run on any modern version of Windows right out of the box, and the source code it completely visible for you to modify.

Setup:
Copy and paste the following text into an empty text file and save it as: SaveAsMHT.vbs

Code: Select all

Option Explicit

Const WshFinished = 1

Const strAppTitle        = "Awasu Save as MHT Send to tool"
Const strGMHTExe         = "gmht.exe"

Const strGMHT_Err_No_Arguments = "Invalid arguments."
Const strGMHT_Err_Bad_syntax   = "Can't download to MHTML: Invalid syntax"
Const strGMHT_Err_Unknown      = "Can't download to MHTML: Unknown error 0x800C0005"
Const strGMHT_Err_Dispatch     = "Can't download to MHTML: IDispatch error #24"

Dim strURL          ' As String
Dim strTitle        ' As String
Dim strOutputDir    ' As String
Dim strDestFile     ' As String
Dim WshShell        ' As WScript.Shell
Dim oExec           ' As WScript.WshExec
Dim strStdOut       ' As String
Dim strStdErr       ' As String
Dim strAwasuProgDir ' As String
Dim fso             ' As Scripting.FileSystemObject
Dim fldrTemp        ' As Scripting.Folder
Dim fileMHT         ' As Scripting.File
Dim strMsg          ' As String
Dim regEx           ' As VBScript.RegExp

If WScript.Arguments.Count < 3 Then
  MsgBox "Error: Invalid syntax - cscript SaveASMHT.vbs URL Title OutputDirectory"
  WScript.Quit(1)
End If ' WScript.Arguments.Count < 3

strURL       = Trim(WScript.Arguments.Item(0))
strTitle     = Trim(WScript.Arguments.Item(1))
strOutputDir = Trim(WScript.Arguments.Item(2))

Set fso = CreateObject("Scripting.FileSystemObject")

'----------------------------------------------------------------------------------
' If the output folder doesn't exist, exit with an error message.
'----------------------------------------------------------------------------------
If Not fso.FolderExists(strOutputDir) Then
  Set fldrTemp = fso.CreateFolder(strOutputDir)

  strMsg = "Error: Output folder: """ & strOutputDir & """ does not exist."
  Msgbox strMsg, vbOkOnly, "Error: " & strAppTitle
  WScript.Quit(2)
End If ' Not fso.FolderExists(strOutputDir)

strURL = Replace(strURL, "%3F", "?") ' Un-url encode the question mark

' Append a trailing backslash if it doesn't already exist.
If Right(strOutputDir, 1) <> "\" Then
  strOutputDir = strOutputDir & "\"
End If ' Right(strOutputDir, 1) <> "\"

'----------------------------------------------------------------------------------
' Find Awasu's installation directory, that's where gmht.exe lives.
'----------------------------------------------------------------------------------
Set WshShell = WScript.CreateObject("WScript.Shell")

strAwasuProgDir = WshShell.CurrentDirectory & "\"
If Not fso.FileExists(strAwasuProgDir & strGMHTExe) Then
  strMsg = "Error: """ & strAwasuProgDir & strGMHTExe & """ does not exist " & _
           vbCrLf & "in the same directory as Awasu.exe." & _
           vbCrLf & "Please move/copy """ & """ strGMHTExe into the same directory as awasu.exe."
  Msgbox strMsg, vbOkOnly, "Error: " & strAppTitle
  WScript.Quit(3)
End If ' Not fso.FileExists(strAwasuProgDir & strGMHTExe)

'----------------------------------------------------------------------------------
' Call gmht.exe, wait for the return message.
'----------------------------------------------------------------------------------
Set WshShell = CreateObject("WScript.Shell")
Set oExec    = WshShell.Exec(strAwasuProgDir & strGMHTExe & " " & strURL & " 0")

Do While oExec.Status <> WshFinished
Loop ' While oExec.Status <> WshFinished

'----------------------------------------------------------------------------------
' gmht.exe has completed, read stdout and stderr,
' remove the trailing carriage return/line feed characters.
'----------------------------------------------------------------------------------
strStdOut = Replace(oExec.StdOut.ReadAll(), vbCrLf, vbNullString)
strStdErr = Replace(oExec.StdErr.ReadAll(), vbCrLf, vbNullString)

'----------------------------------------------------------------------------------
' If stderr has a value display an error message and exit.
'----------------------------------------------------------------------------------
Select Case strStdErr
 
 Case strGMHT_Err_No_Arguments
    MsgBox "Error: " & strGMHT_Err_No_Arguments & vbCrLf & "Please correct your arguments to """ & strAppTitle & """", vbOkOnly + vbCritical, "Error: " & strAppTitle
    WScript.Quit(4)

  Case strGMHT_Err_Bad_syntax
    MsgBox "Error: " & strGMHT_Err_Bad_syntax & vbCrLf & "Please correct your arguments to """ & strAppTitle & """", vbOkOnly + vbCritical, "Error: " & strAppTitle
    WScript.Quit(5)

  Case strGMHT_Err_Unknown
    MsgBox "Error: " & strGMHT_Err_Unknown & vbCrLf & "Verify your URL.", vbOkOnly + vbCritical, "Error: " & strAppTitle
    WScript.Quit(6)

  Case strGMHT_Err_Unknown
    MsgBox "Error: " & strGMHT_Err_Dispatch & vbCrLf, vbOkOnly + vbCritical, "Error: " & strAppTitle
    WScript.Quit(7)

End Select ' strStdOut

'----------------------------------------------------------------------------------
' Move the MHT to the output directory and remane it to the title of the feed item.
'----------------------------------------------------------------------------------
strDestFile = strOutputDir & CleanFileName(strTitle) & ".mht"

On Error Resume Next

If fso.FileExists(strDestFile) Then
  fso.DeleteFile strDestFile
  If Err.Number > 0 Then
    MsgBox "Error: " & Err.Number & " - " & Err.Description & vbCrLf & "The file """ & strDestFile & """ must be locked by another application.", vbOkOnly + vbCritical, "Error: " & strAppTitle
    WScript.Quit(8)
  End If ' Err.Number > 0
End If ' fso.FileExists(strDestFile)

fso.MoveFile strStdOut, strDestFile

' Uncomment the following line (remove the leading apostrophe) to display a confirmation message box
'MsgBox """" & strURL & """ has been saved as """ & strDestFile & """", vbOkOnly, strAppTitle

' Replace invalid Windows file system characters with underscores
Function CleanFileName(strTitle)
  Set regEx = New RegExp

  regEx.IgnoreCase = True
  regEx.Global     = True
  regEx.Pattern    = "[\\\/:*?<>""]"

  CleanFileName = regEx.Replace(strTitle, "_")
End Function ' CleanFileName(strTitle)


Define a new Send to tool named "Save as MHT" (or whatever you want to call it). In the command box, enter the following command line:

Code: Select all

wscript "PathToWhereYouSavedTheFile\SaveAsMHT.vbs" {%URL%} "{%ITEM-METADATA% name!}" "Path to your output directory"


To set up a Send to tool click Edit->Send to->Organize
http://www.awasu.com/help/2.4/Productiv ... Tools.html

Pay special attention to the quotation marks in the above command line. Due to the way that most runtime environments pass space-delimited arguments via the command line, any argument that may contain embedded spaces needs to be wrapped with quotation marks. The URL should be ok; but the item's title, path to the Send to tool, and the output directory will all probably contain embedded spaces so you should wrap them with quotes.

Also the "Command" field of the "Organize send-to's" dialog box is limited to 235 characters. This should be enough characters to hold the complete command, as long as you don't use really long paths to the SaveAsMHT.vbs file and/or the output directory. If you must use really long paths that exceed 235 characters you can write a .BAT file that contains the all of the hard-coded portions of the above command and just pass in the URL and Title.

By making the output directory a parameter to the SaveAsMHT.vbs script you can actually define several instances of "Save as MHT" Send to tool, with different output directories, e.g. "Save as MHT, Health", "Save as MHT, IT", "Save as MHT, News", etc.

Usage:
Open up a Channel Summary Template (CST) that contains the Send to link (any standard Awasu CST). Hover your mouse over the Send to link and select "Save as MHT" from the popup menu. A DOS window will open for a few seconds and if everything goes correctly, an MHT file will be created in the output directory you specified. The MHT file name will be the feed item's title with illegal Windows file system characters replaced with underscores. By default, no confirmation message is displayed, but there is a line of code towards the bottom of the script that you can uncomment (remove the leading apostrophe) if you want a confirmation message with each save.

Error messages will be displayed if:
    The output directory does not exist
    1) Zero or too few arguments are passed
    2) The gmht.exe program is not in Awasu's installation directtory
    3) The URL is invalid
    4) An existing file exists and it is locked by another process (otherwise existing files are silently overwritten).

If you have any problems with setup or running it, post a reply and I'll try to help you.
Last edited by kevotheclone on Wed Jun 10, 2009 7:52 am, edited 2 times in total.

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Re: "Save as MHT" Send to Tool

Post by support » Tue Mar 24, 2009 11:21 am

Woah, this is way cool! Thanks for putting this up :-)

I had one minor problem when setting it up. You locate the Awasu installation directory by checking the <tt>HKEY_CLASSES_ROOT\awasu\shell\open\command\</tt> registry key but this is not always present. You're probably better off looking at <tt>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\AWASU_is1</tt> since this is written by the installer and so should always be there (assuming it was used, of course).

User avatar
kevotheclone
Posts: 245
Joined: Mon Sep 08, 2008 7:16 pm
Location: Elk Grove, California

Re: "Save as MHT" Send to Tool

Post by kevotheclone » Tue Mar 24, 2009 7:56 pm

Woah, this is way cool! Thanks for putting this up


No problem, more coolness to follow. Someday I'll "professionalize" it a bit and add it to the wiki.

You are correct about the registry keys, here's what lead to my decision.

I have Awasu installed on one PC, and I have it running in Portable Mode on a USB drive. On my secondary PC I didn't have the uninstall key, but I had the awasu protocol key, so I assumed that the awasu protocol key was added when you run Awasu, but today with further testing I see I was wrong. The awasu protocol key may have been left over from a time when I did have Awasu installed on the secondary PC; or maybe I manually added it because there's some cool things you can do with it (which I might turn into a future feature request, but that's another day's post).

Anyway... I see that the awasu protocol key is added anytime a user runs admin.exe; regardless of whether they exit via the "OK" or "Close" buttons, just running admin.exe adds the awasu protocol registry key.

So... I'll update the previously posted code to display an error message if the awasu protocol key does not exist. The error message will instruct the user to run admin.exe to add the awasu protocol key to the Windows Registry.

Does this sound like a reasonable solution that would work for both installed and Portable Mode users? :?:

And of course, with the info you previously provided regarding the CDO library, I might even be able to rewrite this to use CDO directly and not call gmht.exe, but that's a future enhancement.

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Re: "Save as MHT" Send to Tool

Post by support » Wed Mar 25, 2009 12:13 pm

kevotheclone wrote:Anyway... I see that the awasu protocol key is added anytime a user runs admin.exe; regardless of whether they exit via the "OK" or "Close" buttons, just running admin.exe adds the awasu protocol registry key.

Yes, that's correct. It's there and not in the installer for historical reasons (wow, Awasu is so old I can say things like that :roll: ), but it's not a problem since I don't think it's used for anything.

kevotheclone wrote:So... I'll update the previously posted code to display an error message if the awasu protocol key does not exist. The error message will instruct the user to run admin.exe to add the awasu protocol key to the Windows Registry.

Even running <tt>admin.exe</tt> is no guarantee since you're not guaranteed of getting the same drive letter every time you mount an external drive. I would try something like this:
- check the installer key I mentioned earlier, since this will cover 99% of all cases.
- check the key you were originally
- one other thing that might work is checking your current directory. Awasu launches your script and so it should inherit Awasu's current directory.

User avatar
kevotheclone
Posts: 245
Joined: Mon Sep 08, 2008 7:16 pm
Location: Elk Grove, California

Re: "Save as MHT" Send to Tool

Post by kevotheclone » Thu Mar 26, 2009 12:33 am

one other thing that might work is checking your current directory. Awasu launches your script and so it should inherit Awasu's current directory.


Why didn't I think of that?

It's simpler to implement and more reliable. Based upon my testing it works correctly regardless of whether you are using a fully installed copy of Awasu or Portable Mode.

Great idea! :coolthumb:

I've also got another update I'll make. I'll verify that gmht.exe actually exists before I'll try to call it. The update should be availble no later than tomorrow (Pacific Standard Time, GMT-08:00).

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Re: "Save as MHT" Send to Tool

Post by support » Thu Mar 26, 2009 11:08 am

kevotheclone wrote:Why didn't I think of that?

It's simpler to implement and more reliable. Based upon my testing it works correctly regardless of whether you are using a fully installed copy of Awasu or Portable Mode.

It took a while for me to think of it as well :-)

And you don't know if Awasu is changing it's current directory internally but hard experience has taught me that this is a really bad idea in a multi-threaded program so I can tell you that I'm pretty sure it doesn't :roll:

User avatar
kevotheclone
Posts: 245
Joined: Mon Sep 08, 2008 7:16 pm
Location: Elk Grove, California

Re: "Save as MHT" Send to Tool

Post by kevotheclone » Mon Mar 30, 2009 12:44 am

I updated the original post using the "current directory" as the directory where gmht.exe is located, and display an error message if gmht.exe does not exist in the "current directory".

FWIW Another option that I thought of using was the Win32_Process class in the Windows Management Instrumentation (WMI) library. IIRC, this should work on Windows 2000 and newer OSs and on older versions of Windows if you manually install WMI. WMI has 100s (?) of classes available that provide a fairly consistent syntax for monitoring the hardware and software of any Windows system that you have user rights to monitor. More info on WMI can be found here:
http://msdn.microsoft.com/en-us/library/aa394582%28VS.85%29.aspx

Microsoft even released a free "WMI Scriptomatic" that will generate some basic code so you can examine what info each WMI class provides.
http://www.microsoft.com/downloads/details.aspx?FamilyID=09dfc342-648b-4119-b7eb-783b0f7d1178&displaylang=en

I even got a crazy idea about writing a Channel Hook that would perform a WMI query to monitor, CPU usage, hard drive space, paging file activity etc. It could be written generic enough to allow the system's name, WMI class, and returned field(s) data to be parameterized, so multiple instances could be defined by creating multiple .hook files. But that's another extension for another day.

Here's an example of obtaining the executable path to a running instace of a process. The "." for the computer name is a shortcut alias for localhost. You could substitute a different computer name and process and user rights permiting you'll see the executable path the process if it's running. In this example I return a null string if it fails. I've got a couple of comment lines that you can enable to see more details if anyone decides to play around this this function.

Code: Select all

Option Explicit

Dim strComputer ' As String

strComputer = "."

MsgBox GetProcessPath(strComputer, "awasu.exe")

Function GetProcessPath(strComputer, strProcess)
  Dim objWMIService ' As SWbemServicesEx
  Dim colProcesses  ' As SWbemObjectSet
  Dim objProcess    ' As SWbemObjectEx
  Dim User          ' As String
  Dim Domain        ' As String
  Dim lngRetVal     ' As Long

  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  Set colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = '" &  strProcess & "'")

  For Each objProcess In colProcesses
    lngRetVal = objProcess.GetOwner(User, Domain)
    If lngRetVal = 0 Then
' Uncomment the next line to display some details of the process during debugging.
'      Wscript.Echo "Process " & objProcess.Caption & " belongs to " & Domain & "\" & User & " on " & objProcess.CSName & " using " & objProcess.ExecutablePath & " with the command line " & objProcess.CommandLine

      GetProcessPath = objProcess.ExecutablePath
      Exit Function
    Else

' Uncomment the next line if you need to debug this.
'      Wscript.Echo "Problem #" & lngRetVal & " getting the owner for process " & objProcess.Caption

      GetProcessPath = vbNullString
      Exit Function
    End If ' objProcess.GetOwner(User, Domain) = 0
  Next ' objProcess
End Function ' GetProcessPath(strComputer, strProcess)

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Re: "Save as MHT" Send to Tool

Post by support » Mon Mar 30, 2009 7:42 am

kevotheclone wrote:I updated the original post using the "current directory" as the directory where gmht.exe is located, and display an error message if gmht.exe does not exist in the "current directory".

I noticed that. Thanks!

kevotheclone wrote:I even got a crazy idea about writing a Channel Hook that would perform a WMI query to monitor, CPU usage, hard drive space, paging file activity etc.

Not so crazy. I thought of something like that ages ago but never got around to writing it.

I'm probably going to be doing a bit of work over the next few weeks with SNMP (for another project) and I've made a note to myself to consider writing a plugin for that, if I get some spare time (ha!).

Picard
Posts: 7
Joined: Thu May 28, 2009 4:15 pm

Use your Script with AutoHotkey..

Post by Picard » Thu May 28, 2009 4:38 pm

Hi guys...

I was searching for tool capable of saving a website-page to a single
mht-file via command line.

I found a freeware, but this one was incapable of doing that in unicode. Is your script able to do that?

I wanted to execute you vbs with a command line, but he is asking me for a gmht.exe. Unfortunately i did not found a hint where i can get this one from. Can you please give me a link to downloal all necessary files?

Thank you for your help.
Picard

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Re: Use your Script with AutoHotkey..

Post by support » Thu May 28, 2009 9:51 pm

Picard wrote:I found a freeware, but this one was incapable of doing that in unicode. Is your script able to do that?

It will save whatever the web server gives it. There isn't really any such thing as "doing it in unicode", it depends on what encoding the page is using and ultimately, it's all just a stream of bytes :roll:

Picard wrote:I wanted to execute you vbs with a command line, but he is asking me for a gmht.exe. Unfortunately i did not found a hint where i can get this one from. Can you please give me a link to downloal all necessary files?

It's part of the Awasu installation.

Picard
Posts: 7
Joined: Thu May 28, 2009 4:15 pm

Post by Picard » Fri May 29, 2009 6:24 am

@ support

I tried the personal edition of Awasu.
But there is no exe called gmht.exe located within the installation folder.
I guess that means i can not get my intent to work? :?
Or do you have another idea? :shock:

Thank you.
With Best Regards,
Picard

User avatar
support
Site Admin
Posts: 3073
Joined: Fri Feb 07, 2003 12:48 pm
Location: Melbourne, Australia
Contact:

Post by support » Fri May 29, 2009 7:46 am

Picard wrote:But there is no exe called gmht.exe located within the installation folder.

It's there. Make you sure installed the latest version (2.4).

Picard
Posts: 7
Joined: Thu May 28, 2009 4:15 pm

Post by Picard » Fri May 29, 2009 4:15 pm

support wrote:It will save whatever the web server gives it. There isn't really any such thing as "doing it in unicode", it depends on what encoding the page is using and ultimately, it's all just a stream of bytes :roll:



I guess you are right, but the thing is:
after saving a sngle URL containing a "Ä" "Ü" "Ö" "ß"
These characters are converted into 1/4....

I guess i can have a look at this by saving this URL:

Code: Select all

http://www.shortbooks.de/SB/shop/obj/book/boShowBook.cfm?PK=1462


With Best Regards,
Picard

User avatar
kevotheclone
Posts: 245
Joined: Mon Sep 08, 2008 7:16 pm
Location: Elk Grove, California

Re: "Save as MHT" Send to Tool

Post by kevotheclone » Mon Jun 01, 2009 6:21 am

Picard, you found Awasu's forums due to your search for a command line tool to save a web page as an MHT file, and you've downloaded Awasu to get the gmht.exe utility and run my VBScript. You may not realize it, but in finding Awasu, you've found the best Atom/RSS/feed software available. I urge you to get to know Awasu, I think you'll be pleased.

Now back to your request for a command line tool for saving web pages as MHT files. Since this isn't really Awasu related, it's a little out of scope of this forum, but if you're still interested post a reply and I might be able to point you in the right direction. Do you know how to code a little bit, particularly in the VB family of languages?

Picard
Posts: 7
Joined: Thu May 28, 2009 4:15 pm

Post by Picard » Mon Jun 01, 2009 9:47 pm

Hi kevotheclone
Thanks for responding....

I am interested in getting this to work,
But i do have no experience coding VBS.

Currently i am searching the web for a solution.
No Success, yet. :twisted:

Thank you anyway.
With Best Regards, Picard

Post Reply

Return to “Awasu - Extensions”