What parameters to pass to mshtml.dll? - windows

I am currently trying to print a HTML file using mshtml.dll. Looking up in the registry I found for html-files, the following print-to entry:
"%systemroot%\system32\rundll32.exe"
"%systemroot%\system32\mshtml.dll",PrintHTML "%1" "%2" "%3" "%4"
Unexpectedly there are some parameters to pass to mshtml.dll, what are the parameters of mshtml.dll (numbered %1, %2, %3, %4 in this registry information)?

You found this in the printto verb of the htmlfile progid. Which runs when you drag an HTML file from Explorer and drop it on a printer shortcut. The printto verb has these arguments:
%1: the path to the HTML file
%2: the printer name
%3: the printer driver name (optional)
%4: the printer port name (optional)
Taking a dependency on an undocumented function is unwise, you can't rely on this still working in the next Windows version. Using WebBrowser.Print() is the documented way. IWebBrowser2::ExecWB() in native code.

Neither the printer's name is mandatory, in fact in the "print" verb of the htmlfile progid only one parameter is specified for the same command.
By the way: I tried to replace %2 with the printer's name (with and without quotes) but it didn't do anything different, that is, the print dialog is still there.
Tried on Windows 10 and Windows 7.

Related

How to escape & ampersand in Custom protocol handler in Windows

I made a custom protocol handler following this link. The case is I need to open a link which can only be opened in IE and might contains several query parameters and should be opened in IE from our web app which is running on Chrome (this is really annoying). After many tries and fails, I managed to find the snippet to add entry to the windows registry hive and made .reg file and run:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\ie]
"URL Protocol"="\"\""
#="\"URL:IE Protocol\""
[HKEY_CURRENT_USER\Software\Classes\ie\DefaultIcon]
#="\"explorer.exe,1\""
[HKEY_CURRENT_USER\Software\Classes\ie\shell]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open]
[HKEY_CURRENT_USER\Software\Classes\ie\shell\open\command]
#="cmd /k set myvar=%1 & call set myvar=%%myvar:ie:=%% & call \"C:\\Program Files (x86)\\Internet Explorer\\iexplore.exe\" %%myvar%% & exit /B"
It worked but the problem is if a link contains more than 1 query params, all but the first are omitted, I am sure this because of character encoding in windows command line:
e.g. some_example_url?query1=value1&query2=value2&query3=value3 is becoming some_example_url?query1=value1
I find this solution but it did not work either. How can I properly escape & character, so that it can be opened on IE with all query parameters. (as before mentioned link is triggered by web app running on Chrome)
EDIT: The code which triggers:
fileClicked(url) {
// url should be escaped with ^
const escapedUrl = url.replace(/&/gi, '^&');
const ie = document.createElement('a');
// ie: scheme => custom protocol handler
// host computer (windows) should add custom protocol to windows registry
ie.href = `ie:${escapedUrl}`;
ie.click();
}
EDIT 2
#muzafako fixed the script, just last line should be replaced like below:
#="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"
You don't need to decode query parameters at all. I've tried to find solution for this issue and saw this answer. Its works for me. just change command line to:
#="cmd /c set url=\"%1\" & call set url=%%url:ie:=%% & call start iexplore -nosessionmerging -noframemerging %%url%%"

Change Case of Programming Syntax

I was wondering if there was a simpler way to change the case of just the highlighted colored programming text (For In While Do Set etc) in one go by color using notepad++ or sublime text. So for example change the case of all the blue text in a batch file test.bat:
SETLOCAL DisableDelayedExpansion
FOR /F "delims=" %%A IN ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c
ECHO(0x09"') DO SET "TAB=%%A"
ECHO This is a %TAB%
The syntax would be changed to title case like:
Setlocal DisableDelayedExpansion
For /F "delims=" %%A In ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c
Echo(0x09"') Do Set "TAB=%%A"
Echo This is a %TAB%
I currently do this by Right Clicking and then selecting Plugin Commands> Copy Text with Syntax Highlighting from the context menu, copying this text to Microsoft word and saving it as an html file, opening the html file in notepad++ for editing and then pasting text-transform: uppercase; under the line color:blue; and then opening it again in word (not in edit mode) and finally copying it to notepad++ but would like to know if there is a simpler way without looking up each individual word but instead just batch formatting words of a similar color.
Sublime has an internal command called title_case to perform this manipulation, which is available from the menu as Edit > Convert Case > Title Case or from the command palette as Convert Case: Title Case.
So if all of the keywords in the document were selected, you could use that command to perform the operation. You would probably have to do it in batches (pun mildly intended), such as putting the cursor in SETLOCAL and repeatedly pressing Ctrl+D to select all of the instances, then cycle back and do the next keyword.
To automate the process a little better, a simple plugin can be created that selects all of the keywords and runs the command, so that you can perform the bulk of the operation in one simple step.
An example of that is the following, which you can use by selecting Tools > Developer > New Plugin... from the menu, replacing the stub code with the code below, and then saving in the location Sublime will default to as something like dos_batch_case_fix.py or something similar (only the location and extension matter):
import sublime
import sublime_plugin
# A list of extra words to change the title case for that aren't considered
# keywords by the dos batchfile syntax.
_extra_words = ["do", "in"]
class BatchTitleCaseCommand(sublime_plugin.TextCommand):
"""
For a dos batch file, convert the case of all keywords and all found
instances of the words in _extra_words to title case.
"""
def run(self, edit):
# Save the current selection, then clear it
saved_sel = list(self.view.sel())
self.view.sel().clear()
# Find everything that the syntax thinks is a keyword and add it to
# the selection
for region in self.view.find_by_selector("keyword"):
self.view.sel().add(region)
# Convert the list of extra words to a regular expression and add all
# whole word matches to the selection.
regex = r"\b({0})\b".format("|".join(_extra_words))
for region in self.view.find_all(regex, sublime.IGNORECASE):
self.view.sel().add(region)
# Convert the selection to title case.
self.view.run_command("title_case")
# Restore the selection to what it was on entry.
self.view.sel().clear()
for region in saved_sel:
self.view.sel().add(region)
def is_enabled(self):
return self.view.match_selector(0, "source.dosbatch")
This implements a new command named batch_title_case that is only active in batch files. It saves the current selection, then selects all of the keywords (as determined by the syntax currently in use), runs the command to change the case, then puts the original selection back. You can bind this command to a key the same as you would for any other internal command.
Since this uses the syntax of the current file to detect what a keyword is, it doesn't catch things like IN and DO because (at least currently) the Sublime syntax for Batch files doesn't think those are keywords.
For that reason, this also shows how you could handle those sorts of words. The code here does a case insensitive whole word search for a list of words (represented in _extra_words) and selects those as well as the selected text.
This is semi-dangerous in that unlike the keyword search by syntax scope, the regex search will find those words anywhere, including inside of strings where they might not represent keywords but just regular words instead.
As such it's probably a good idea to use this on a copy of the file (or be able to undo) and verify that it hasn't done something that you didn't otherwise expect.
I would imagine that a visual inspection would be much less effort than the solution you're currently using.
Potential changes
If desired, the plugin above could be modified to remove the portions that save and restore the selection along with executing the title_case command; in that case the command would only alter the selection in the file to the words that it thinks that it needs to title case and allow yo to take the action manually.
Note that if you work with a really large file that contains a lot of keywords, having that many simultaneous selections may slow things down a bit.
Invoking the command
The plugin above creates a command named batch_title_case. There are a variety of ways to execute the command, depending on how you want to proceed. Where the User package is mentioned below, you can use the Preferences > Browse Packages command from the menu to locate it. The User package is the location where the plugin above is stored, since Sublime defaults to that location when you use Developer > New Plugin.
Via a key binding
Using Preferences > Key Bindings, you can add a custom binding to the right hand side of the window that references the command:
{
"keys": ["ctrl+alt+s"],
"command": "batch_title_case",
},
Via the Command Palette
The command can be added to the command palette by adding a file of type sublime-commands to your User package with the following contents (e.g. MyCustomCommands.sublime-commands). The caption will specify how the command appears:
[
{ "command": "batch_title_case", "caption": "Command Caption Here" },
]
Note: As written above, the command is only enabled for a batch file, and the Command Palette only shows you available commands, so in non-batch files the command will not appear in the command palette.
Via the context menu
The command can be added to the right click context menu by creating a file named Context.sublime-menu in your User package; if such a file already exists, add only the { ... } line to the appropriate place in the existing file. The caption will specify how the command appears:
[
{ "command": "batch_title_case", "caption": "Command Caption Here" },
]
Note: As written above, the command is only enabled for a batch file, so in non-batch files the command in the menu will appear grayed out. To hide the context menu item in files that it doesn't apply to, add the following lines to the plugin code above under is_enabled():
def is_visible(self):
return self.is_enabled()

Post-Build Event Works With one Project But Not the Other

I have 2 projects for which I am trying to create a generic Post-Build event batch file.
Here is the command in Visual Studio:
Post-Build event
if $(ConfigurationName) == Release ("$(ProjectDir)PostBuildRelease.bat" "$(TargetDir)" #(VersionNumber) "$(TargetFileName)" "$(TargetName)")
So I am calling the file PostBuildRelease.bat with 4 parameters:
Bin\Release Directory
Project Version
File Name With Extension
File Name Without Extension
Project 1
This works perfectly with this batch script:
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\LyncVdiChecker\"
MOVE %productionpath%%3 %productionpath%"_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 %productionpath%
Where the assembly is copied to Z:\Unused\Apps\LyncVdiChecker\ and the existing version copied to _archive in the same folder. The archived version also has the date and version number replace the file extension.
Project 2
This batch script also works perfectly (it does the same thing but in a different folder and for a different project):
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\IT Support App\"
MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"
However, if I try using the same script from Project1 (the more generic version) in Project2, I get errors, even though the 2 scripts are equivalent:
Errors
The command "if Release == Release ("C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\PostBuildRelease.bat" "C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\bin\Release\" 2.0.6100.20905 "IT Self Help.exe" "IT Self Help")" exited with code 4.
Output Window:
The syntax of the command is incorrect.
Invalid number of parameters
This error is rather unhelpful, so I tried commenting out the 2 lines MOVE and XCOPY and build again:
Removed MOVE
Same error as above.
Output window:
Invalid number of parameters
Remove XCOPY
No Visual Studio Error, but this appears in the output window:
The syntax of the command is incorrect.
Parameter Output
When I echo out the parameters being used in Project2, everything seems to be in order:
"Path\to\Bin\Release"
2.0.6100.21082
"IT Self Help.exe"
"IT Self Help"
Z:\Unused\Apps\IT Support App\
How can I debug this issue? How is it possible that my script runs fine without any issues, but when run against a different project none of the commands are recognised? Any help with this is much appreciated!
You should normalize all your arguments, so they don't contain outer quotes.
Then you can use them in a reliable way.
The syntax set "variable=%~1" avoids outer quotes in the variable itself.
set "TargetDir=%~1"
set "VersionNumber=%~2"
set "TargetFileName=%~3"
set "TargetName=%~4"
SET "productionpath=Z:\IT Support App\"
set "dateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"
MOVE "Z:\IT App\%TargetFileName%" "Z:\IT App\_archive\%TargetName%.%dateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "Z:\IT App"
The problem is that the script is messing with the double quotes resulting in invalid paths and invalid number of arguments passed. When dealing with paths built dynamically, it's best to strip any existing " from the parts, and after the path is complete, surround it in ".
Dealing with batch arguments is explained on MSDN. Same thing for variables can be found on SS64.
I've played a bit with the file, and I was able to run it (from command line). The changes you should make in your (Project1) file:
SET productionpath="Z:\Unused\Apps\LyncVdiChecker\"
MOVE "%productionpath:"=%%~3" "%productionpath:"=%_archive\%~4.%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%-%~2"
XCOPY "%~3" "%productionpath:"=%"
I moved the " from the productionpath line to the beginning of its contents. That way will work with paths that contain SPACE s.
In the MOVE and XCOPY lines, I did what I explained above: even if the syntax is not that clear, it's more robust (the last "%productionpath:"=%" could be simple written as %productionpath%, but I left it in the the 1st form for consistency).
Note: You could remove the CMD command at the beginning of your batch, since it starts a new cmd instance(process) that doesn't end.
I found a solution to this, but I am still not sure what the cause was.
I suspect it has something to do with either one of:
Spaces in productionpath causing the command parameter declaration to escape
Quotes around one or more of the parameters creating a non-existent file path
After trying out a few changes to the script, I found that changing the productionpath declaration to SET productionpath="Z:\Unused\Apps\IT Support App\" solved the issue:
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET productionpath="Z:\Unused\Apps\IT Support App\"
MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"
Making the same change to the Project1 script did not cause that to break either, so this seems safe.
Update
After reading some of the other answers, I amended the script once again to the following:
CMD
SET "TargetDir=%~1"
SET "VersionNumber=%~2"
SET "TargetFileName=%~3"
SET "TargetName=%~4"
SET "ProductionPath=Z:\Unused\Apps\IT Support App\"
SET "ArchivePath=%ProductionPath%_archive\"
SET "DateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"
MOVE "%ProductionPath%%TargetFileName%" "%ArchivePath%%TargetName%.%DateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "%ProductionPath%"
Notice the "normalisation" of the paramaters - this removes all quotation marks from their values.
Also now using named parameters.

Run command with parameters in batch file

Assume a psuedo command:
psuedocmd.exe
It has various parameters like:
/scan /save /savefolder
Now i want to run psuedocmd.exe using batch file.
And i would like to use parameters too.
I am using the following line in batch file
psuedocmd.exe /scan /save
But in this case psuedocmd.exe is running without the parameters.
Try putting parameters between quotes "parameter value", especially if paths have spaces in them.
Check if the batch text file is not saved in some encoding making your / be read as an escape character.
If you want to run the .exe by handing over parameters from the batchfile, don't use variables, just use %1, %2, etc.
run.bat /save /folder
Where run.bat's contents are:
pseudocommand.exe %1 %2
Hehe, after over half a year, I'm out of patience..
You must provide the savefolder parameter when using the save parameter in Acunetix Web Vulnerability Scanner, making that line in your batch-file look like:
wvs_console.exe /scan "http://www.aaa.com" /save /savefolder "c:\log"
Excerpt from the documentation:
/scan Scans a single website.
Syntax: /scan [url]
Example: /scan http://testphp.vulnweb.com
/save Saves scan once scan is finished. The file will be
saved in the location specified by the “/savefolder” switch.
Syntax: /save
/savefolder Specify the folder were all the scans and other
scan related files will be saved.
Syntax: /savefolder [directory]
Example: /savefolder C:\Acunetix\Scans

Creating Custom Protocol (Windows 7)

I've been trying to create a custom protocol (open_php_file://) to open local files through the browser. I've created the following registery-keys:
HKEY_CLASSES_ROOT
open_php_file
(Default) = "URL:PHPEd protocol"
URL Protocol = ""
DefaultIcon
(Default) = "phped.exe"
shell
open
command
(Default) = "C:\Program Files (x86)\NuSphere\7.0\phped.exe" "%1"
The problem is: I can't open files in my browser (example: open_php_file://c:\file.txt), and the protocol isn't listed in the windows default programms.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\openphpfile]
#="\"URL:openphpfile Protocol\""
"EditFlags"=hex:02,00,00,00
"URL Protocol"=""
[HKEY_CLASSES_ROOT\openphpfile\DefaultIcon]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\",0"
[HKEY_CLASSES_ROOT\openphpfile\shell]
[HKEY_CLASSES_ROOT\openphpfile\shell\open]
[HKEY_CLASSES_ROOT\openphpfile\shell\open\command]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\" -c \"%1\""
Basically the problem was with the underscores in your protocol.Once removed everything started working fine.You can change the path of executable as per your wish i.e. "C:\Program Files (x86)\NuSphere\7.0\phped.exe".
I tried openphpfile:blast and it worked quite nicely :)
EDIT:
the problem with this solution is that %1 gets replaced with
"open_php_file://[file]" instead of just "[file]". This way I need
some sort of filter that chops "open_php_file://".
put a space after openphpfile:[Space]Your_Content and change parameter to %2 you will get the expected result
[HKEY_CLASSES_ROOT\openphpfile\shell\open\command]
#="\"C:\\Users\\ABC\\Documents\\Programs\\CB\\Chunks\\CGI.exe\" -c \"%2\""
Windows always replaces %1 with the full URI that was entered. AFAIK there is no way to change that behavior.
This leaves you two options:
If you've written the program being called yourself, you can filter the URI when it is being invoked.
You could use an intermediate program that acts as a filter for the URI and then forwards the result to the actual protocol implementation. Fortunately for you, someone has already done exactly that. See 'CustomURL' on CodePlex. CustomURL is a small utility for registering custom URL protocols. For example you can associate the rdp:// protocol with Remote Desktop Client or the ssh:// protocol with Putty or another SSH client.

Resources