Check if WMIC is installed, writing data into files from batch file - windows

I am using the Windows Management Instrumentation Command-line (WMIC) for reading data from a computer like it's Hardware components and IP settings.
As I am using a batch file (Windows) for filling files for each computer/node with data the query logic is implemented there. So far it has been working quite good on my computer and others I have tried on.
The problem is on computers where the WMIC has not been used before, it's neccessary to (automatically) be installed at the first query/execution. This is why the console program prints out "Please wait while WMIC is being installed".
As I am writing to my file this is a problem: I don't want to have this string in it. Another problem is, that if the string is output it crashes all my file. "Please wait while WMIC is being installed" is represented in ASCII, the results of the data queries are somehow written as ASCII characters with leading zeros (multi-byte character set? unicode? ...).
Does someone know how to check if WMIC is alread installed?
Or: how to ignore the string?
Or: do I really have to implement a converter in my file viewer which checks for the string/ character set?

Since that is only printed on the very first run of WMIC, you can just make two calls. One dummy one to eat away the string:
wmic foo >nul 2>&1
and after that what you actually wanted to execute.

Related

Print file to printer or default printer through command prompt in windows 10

I have a file located at C:\printme.txt
I want to print it to my printer which is named POS80
Is there not a simple command for windows in the command prompt to say Print C:\printme.txt to POS80?
It should be noted that POS80 is also the default printer so a command that does not include the printer name but just sends to the default printer would be acceptable too.
Your mileage can vary using the legacy command Print
It MAY work if you have a line printer set to LPT1 and worth trying
Print C:\printme.txt "POS80" However I expect you are getting the error message "Unable to initialize device PRN" that is not unusual as PRN was traditionally LPT1.
Later you say its USB connected. which means its serial (old Com ports) whereas Line Printer (old LPT ports) were parallel hence the potential needs for fettling, but in windows you can use the port name for the printer and that resolves ports issue (files can become ports or vice versa) thus no real problem.
Now you could try messing with printer port redirections to get around that but it would likely mess up other application printing. Thus by far the simplest is make the printer the default one which is what you have.
To avoid the Save Output File As dialog when adding a print job to the default queue, ensure that your default printer isn't Microsoft XPS Document Writer, Microsoft Print to PDF, or other print-to-file options.
So what is Windows 10 doing when you right click print? Generally it fires up the associated FTA (File Type Application) which for .txt (or similar chosen) is NotePad.
Thus the simplest way to command line print plain text is
NotePad /pt C:\printme.txt "POS80"
NotePad settings can be changed in the registry before and after you print, via the command line, even skewing letters (fun to prank colleagues if you use 1 degree off kilter), however you cannot set line spacing or add graphics, for those you need to step up to WordPad which will accept docx, rtf, odt and most simple text file types.
Several other file types can also be printed in a similar way such as graphics images, using mspaint.
Later you say you are sending html as text and want graphic output not textual.
So the x problem is the files are not plain.txt they are plain.htm so need translation from html by graphic conversion (rendering) to pass through a printer language converter (printer driver) That's a totally different question but the answer is still much the same.
Traditionally you would simply use
rundll32.exe mshtml.dll,PrintHTML "C:\printme.txt"
But security exploits have made that simplicity more of a challenge thus
best to run it like this.
cd /D C:\Windows\System32 & rundll32.exe mshtml.dll,PrintHTML "C:\printme.txt"
And Microsoft Current Policy is "User confirmation is needed to print an HTML page through MSHTML.DLL." thus you need to hit print using sendkeys.
If your preference is FireFox rendering, from the command line you needed to install an extension, however with tightened security in windows 10, I dont know if that's still possible.
If you wish to print xml or html graphically in windows 10+ you can ask Edge --headless to print those for you to PDF, either as screen shot or rendered text, silently without enforced html confirmation ! And again you can print html automatically by using sendkeys to replace the user.
However printing PDF from the command line is where the real fun begins.
It is possible if the PDF is the correct type prepared for the printer (even a simple thermal or inkjet) then an old school copy /b file.pdf "printer" may work but dont send a big file to test, just a tiny Hello World!, or your carbon neutrality is instantly wiped out by reams of paper with one or two letters each.
My dirt cheap HP accepts files that can be viewed as PDF that start textually like this i.e. which have the PCLm 1 comment.
%PDF-1.7
%PCLm 1.0%
223 0 obj
<<
/Type /Page
/Parent 2 0 R
/Resources <<
/XObject <<
/Image0 3 0 R
/Image1 4 0 R
For most POS printers a PDF either needs to be processed in middleware or usually top end firmware such as onboard Direct PDF
Thus we come back to using html bitmap and text directives that will either need a print driver or be programmed to a port or file for later copy /b to device.
As you no doubt know Microsoft have not made it simple to print file.html default in fact the opposite resulting in many third part apps for win xp-win 11 such as https://www.bersoft.com/htmlprint/index.htm#overview amongst many other options.

UTF-8 on Windows with Ada

It is my understanding that by default, Character is Latin_1, Wide_Character is UCS-2, and Wide_Wide_Character is UCS-4, but that GNAT can have specified pragma Wide_Character_Encoding(UTF8); or -gnatW8 and that those characters and their strings will be UTF-8 encoded instead.
At least on Linux and FreeBSD, the results fit with my expectations. But on Windows the results are odd.
For either Wide or Wide_Wide variants, once a character moves beyond the ASCII set, I get a garbled mess. I beleive this is called emojibake by some. So I figured it was a codepage issue. After all, the default codepage in Windows, and therefore what the Console Host would load with, is 437 which isn't the UTF-8 codepage. chcp 65001 and now instead of the mess of extra characters, there's an immediate exception raised ADA.IO_EXCEPTIONS.DEVICE_ERROR : a-ztexio.adb:1295. Looking at where the exception occurred, it seems to be in the putc binding of fputc(). But this is Standard_Output, shouldn't an EOF never happen?
Is there some kind of special consideration Windows needs? How can I get UTF-8 output?
edit:
I tried piping the output into a text file. The supposed UTF-8 encoded program still generates emojibake in the file. Not sure why this would immediately throw an exception in the console though.
So then I tried directly opening and writing to a file instead of the console/pipe. Oddly this works exactly as it should. The text is completely correct.
I've never seen this kind of behavior with any other language, so it should still be possible to get proper UTF-8 at the console, right?
The deficiency so many others, not just here, describe in the Windows Console Host has either been fixed or never existed in the first place. Based on this document, I feel it was probably always very misunderstood. Windows doesn't treat the console like files, and it's easy to fall into that trap.
Using this very straight forward code, along with what Windows needs and expects behind the scenes...
It correctly produces the following, as long as either pragma Wide_Character_Encoding(UTF8); or -gnatW8 is used.
Piping the output of this test program into a file works as it should. Similarly, piping the output of this test program into another program works as it should. And also similarly, taking the file from piped output, and piping it into another program works as it should.
Full UTF-8 behavior as one would expect under Linux, on Windows.
What needs to be done is twofold. In the package initializer, the Console Host needs to be told what it's working with, which can be done like this.
Character output is then done through fputwc. According to MS Docs fputc should never be used for UNICODE on Windows, which is part of the problem GNAT has. String output and character/string input is all similar.
Based on others comments and some further research to confirm, I'm pretty sure this is a deficiency of the Windows Console Host.
edit: don't listen to this

MS-DOS Pipe the content of a file into a variable

I am trying to send the content of a text file (which is just one word) into a variable in MS-DOS.
I tried doing it with pipes like so ,without any success
TYPE username.txt | %savedName%
Can anyone enlighten me?
for /f "delims=" %%i in (username.txt) do set "savedname=%%i"
echo savedname=%savedname%
should work for you (as a batch file). If you are executing directly from the prompt, then reduce each %% to %.
If you are nunning this on a Windows machine using WIN NT4, Win2000, WINXP, WIN7, Vista or Win8 then this should work (as also the set/p approach should have worked)
If you are using Win95, Win98, WinME or real MSDOS, then a different approach would be required.
"MSDOS" is often used to mean "Command Prompt" - a generic term ridiculously misapplied to mean "A windows application which emulates the functionality of the MSDOS command-interpreter (with enhanced functionality)". Unfortunately, since "AWAWETFOTMCI(WEF)" is such a mouthful, many people abbreviate it to "MSDOS" or "DOS". This raises the ire of that sad section of the computing community that is more interested in asserting that MSDOS no longer exists than in communicating effectively.
this one is working fine and simpler
set /p SCHEMAS=<schemas_file.txt

What do I need to read to understand $PATH

I'm new to programming/development and I'm having trouble installing development tools.One of my biggest problems when installing something is understanding the shell or terminal (are they the same thing?) and how it relates to installing tools like uncrustify for example. What do I need to read to understand the shell/terminal and $PATH?
Have you tried Googling?
Environment variable
PATH (variable)
(I think you're getting good advice so far on PATH)
The most generic description of a shell is that is a program that facilitates interaction w programs. Programs facilitate 'communication' with the OS to perform work by the hardware.
There are two modes that you will normally interact with a shell.
a command-line processor, where you type in commands, letter-by-letter, word-by-word until you press the enter key. Then the shell will read what you have typed, validate that it understands the general form of what you have asked for, and then start running the 1 (or more) programs specified in what you have typed.
a batch-script processor. In this case you have assembled all of the commands you want executed into a file, and then thru 1 of several mechanisms, you arrange to have the batch-script run so it will in turn run the commands you have specified and the computer does your work for you. Have you done a Windows .Bat file? same idea, but more powerful.
So, a terminal widow is program that is responsible for a. getting input and b., printing output. When you get to the c-programming that underlies the Unix system, you are talking about a feature of the OS design which are called Standard In and Standard Out. Normal unix commands expect to read instructions from StdIn and print output to StdOut.
Of course, all good programs can get their input from files and write there output to files as well, and most programs will take over the StdIn/Out and process files instead of reading input from the keyboard and/or writing to the screen.
To return to the shell, this program that lets you type while the terminal window is open. There are numerous versions of the shell that you may run into AND have varying levels of features that support a. interactive-mode, b. batch-script mode.
To sum it up, here a diagram of what is involved (very basically) for terminal and shell
(run a) terminal-window (program)
shell-command-prompt (program) (automatically started as subprogram)
1. enter commands one at a time, with input from
a. typed at keyboard (std-in)
b. infile
and output to
a. screen (std-out)
b. outFile
program
calls OS level functions for
a. computation
b. I/O
OR 2.
(run the shell program without a terminal, usually from the cron sub-system)
shell-batch-processor
shell program reads batch-script file, 1 'statement' at a time
validate statements
run program, relying on script or cfg to provide inFile data and
indicate where to put outfile data.
I hope this helps.

(MS-DOS) Time Delays

I came past a few ways to cause a time delay such as pings and dirs. Though none of them are really precise, is there anny proper way to cause a time delay?
I heard about a few things though they don't work on all computers, not on my Windows XP nor the Windows NT at college.
It takes ages going through all files on Google finding a good answer, and since I didn't yet find the question on Stack Overflow I thought it might be good to just create the question myself ;)
Sleep
It will allow you to do this.
<warning>This is a hack</warning>
Use your favorite programming language (other than MS-DOS batch) and create an application which takes one argument, the number of milliseconds to wait, then, simply call this program from a batch file to sleep the required amount.
As far as I know, this is the only reliable way to do it in DOS.
If you don't have the ability to send another program along with the batch file, use DEBUG to write a sleep command on the fly, and execute it.
EDIT:
The above answer was kind of toungue-in-cheek. I wouldn't run a batch file that had some DEBUG trickery in it. I believe the traditional way to use a delay in a batch file is the CHOICE commad.
type nul|choice /c:y /t:y,nn > nul
Which of course, doesn't work in XP, since that would be WAAYY too convenient.
"...proper way...."
you can't do that in DOS.
It is possible to achieve a precision of a few miliseconds, depending on your machine's speed.
I have just finished creating such a batch, and though I won't share with you the actual code, I'll give you some pointers:
Use %time% variable, and devide into substrings (without ":" and ".") - one substring will get the seconds, the other - minutes (you may add hours, for delays of over an hour, and even incorporate the date)
Use set /A to transform the time variables into 1 integer representing the amount of seconds which have passed since a rounded hour (X:00:00.00). Add the inputed delay (in seconds) to that.
Create a short loop, comparing the value of the combined var (explained in section 2) to the current time (need to recalc the curent combined min+sec value, inside this loop), and exiting the loop when the match is true.
One major bugfix here - you'll need to truncate any preceeding zeros to variables which are about to get evaluated in a "set /A" command. I've noticed that the console's evaluator (for this command) returns an error when an integer with a preceeding 08 or 09 (or simply 08 or 09) is used.
Remark:
This will only work with command extensions enabled. To test it, use the following at the beginning of the routine:
verify other 2>nul
setlocal enableextensions
if errorlevel 1 goto err
And then add an error handler subroutine named "err".
If you'd want to continue your batch in the same file, use "endlocal" after the looping subroutine.
BTW, this applies ONLY to Windows XP service pack 2 or 3.

Resources