Opening a binary file handled by C++ std::ifstream in gem5 syscall emulation fails is_open check - gem5

I have mnist.loader.hpp header file that opens and reads t10k-images-idx3-ubyte and t10k-labels-idx1-ubyte binary files in a given path using std::ifstream as can be seen in the snippet below:
std::string imagePath = dataDir + std::string("t10k-images-idx3-ubyte");
std::string labelPath = dataDir + std::string("t10k-labels-idx1-ubyte");
std::ifstream imageStream(imagePath, std::ios::binary);
std::ifstream labelStream(labelPath, std::ios::binary);
The path of the directory having those two binary files dataDir is embedded in mnist_caffe.cpp. It could be changed as per my setting in the std::string dataDir = "data/" line.
I set dataDir to /home/mohamed/, then compiled and statically-linked an aarch64 executable out of them and my target is to simulate it on gem5.
The problem:
gem5 always fails to read the files. It gives "Failed to read /home/mohamed/t10k-images-idx3-ubyte".
If we have a look once again at mnist_loader.hpp, we will notice that this error message is due to either the file not being open as or being opened but can't be read :
if (!imageStream.is_open())
{
std::cerr << "Failed to load " << imagePath << std::endl;
return nullptr;
}
or
imageStream.read(reinterpret_cast<char*>(&magic), sizeof(magic));
if (magic != 0x03080000)
{
std::cerr << "Failed to read " << imagePath << std::endl;
return nullptr;
}
or
if (!imageStream.good())
{
std::cerr << "Failed to read " << imagePath << std::endl;
return nullptr;
}
My guess is that gem5 can not open the file in the first place!
My trials:
(I am only interested in opening and reading t10k-images-idx3-ubyte for now)
1- Trying to pass the file to the stdin using -i option: $ ./build/ARM/gem5.opt ./configs/example/se.py -c mnist_caffe -i '/home/mohamed/t10k-images-idx3-ubyte'
2- Using -o: $ ./build/ARM/gem5.opt ./configs/example/se.py -c mnist_caffe -o "-i /home/mohamed/t10k-images-idx3-ubyte"
3- Using --redirects: $ ./build/ARM/gem5.opt ./configs/example/se.py -c /home/mohamed/NNDeploy/ML-examples/armnn-mnist/mnist_caffe --redirects /home/mohamed/t10k-images-idx3-ubyte=/home/mohamed/t10k-images-idx3-ubyte
4- Opening the binary file in the host system using xxd and then passing it to stdin: $ ./build/ARM/gem5.opt ./configs/example/se.py -c ~/NNDeploy/ML-examples/armnn-mnist/mnist_caffe -o " -i /usr/bin/xxd /home/mohamed/t10k-images-idx3-ubyte"
All the above resulted in the same failed-to-read message. I ran out of ideas and it would be great if someone could provide some suggestions!

Related

How to move files and folders to Trash programmatically on macOS?

All I can find on this topic is mentions of FSMoveObjectToTrashSync function, which is now deprecated and no alternative is listed for it.
How to do it from C or Objective-C code?
Use NSFileManager:
https://developer.apple.com/documentation/foundation/nsfilemanager
trashItemAtURL:resultingItemURL:error:
Moves an item to the trash.
In C, you can use AppleScript to move files to the trash. Here's a simple example:
#include <stdio.h>
#include <stdlib.h>
#define PATH "/tmp/"
#define NAME "delete-me.txt"
int main() {
int status;
/* Create a file */
FILE *f;
f = fopen(PATH NAME, "w");
if (!f) {
fputs("Can't create file " PATH NAME "\n", stderr);
return 1;
}
fputs("I love trash\n", f);
fclose(f);
/* Now put it in the trash */
status = system(
"osascript -e 'set theFile to POSIX file \"" PATH NAME "\"' "
"-e 'tell application \"Finder\"' "
"-e 'delete theFile' "
"-e 'end tell' "
">/dev/null"
);
if (status == 0) {
puts("Look in the trash folder for a file called " NAME);
}
else {
puts("Something went wrong. Unable to delete " PATH NAME);
}
return 0;
}
A few notes:
Multi-line scripts have to be sent as multiple -e command line options.
Since osascript insists on printing status messages to the command line console, I've redirected its output to /dev/null. But, if a file of the same name already exists in the trash, then the deleted file will be renamed. If you need to know this name, you'll have to use popen() instead of system() and parse the return string from osascript.

receive Error code 500 when visiting a cgi file (in c++)

I wrote the following code in a file named test.cpp on godaddy web host:
#include <iostream>
using namespace std;
int main () {
cout << "Content-type:text/html\r\n\r\n";
cout << "<html>\n";
cout << "<head>\n";
cout << "<title>Hello World - First CGI Program</title>\n";
cout << "</head>\n";
cout << "<body>\n";
cout << "<h2>Hello World! This is my first CGI program</h2>\n";
cout << "</body>\n";
cout << "</html>\n";
return 0;
}
And I compile test.cpp on the godaddy host using "g++ test.cpp -o a.cgi".
Then I tried to access the cgi (type "www.XXX.com/a.cgi"), the error code 500 came out. I have no idea what went wrong.
Change the permissions of the file using file manager to make it executable
try www.xxx.com/cgi-bin/a.cgi
changing a.cgi to a.cpp and then check if it works

How to code "git commit" in libgit2?

I have searched Google and Stackoverflow for an answer to the question of how to code the equivalent of
git commit -a -m "message"
in libgit2 (https://libgit2.github.com) and C or C++.
But I cannot find a ready and working answer to this question.
I am using libgit2-0.21.
Below is code that initializes a git repository, adds two files to it, and stages the two files so they are ready to be committed.
My question is how to code "git commit -a -m "msg" in libgit2?
#include <sys/stat.h>
#include <string>
#include <fstream>
#include <iostream>
#include <git2.h>
using namespace std;
int main (int argc, char** argv)
{
git_threads_init ();
// Create repository directory.
string directory = "repository";
mkdir (directory.c_str(), 0777);
// Initialize the repository: git init.
git_repository *repo = NULL;
int result = git_repository_init (&repo, directory.c_str(), false);
if (result != 0) cerr << giterr_last ()->message << endl;
// Store two files in the repository directory.
ofstream file;
file.open ("repository/file1", ios::binary | ios::trunc);
file << "Contents of file one";
file.close ();
file.open ("repository/file2", ios::binary | ios::trunc);
file << "Contents of file two";
file.close ();
// Run the equivalent of "git add ."
// Get the git index.
git_index * index = NULL;
result = git_repository_index (&index, repo);
if (result != 0) cerr << giterr_last ()->message << endl;
// Add all files to the git index.
result = git_index_add_all (index, NULL, 0, NULL, NULL);
if (result != 0) cerr << giterr_last ()->message << endl;
// Write the index to disk.
result = git_index_write (index);
if (result != 0) cerr << giterr_last ()->message << endl;
// Run the equivalent of "git commit -a -m "commit message".
// How to do that through libgit2?
// Run "git status" to see the result.
system ("cd repository; git status");
// Free resources.
git_index_free (index);
git_repository_free (repo);
git_threads_shutdown ();
return 0;
}
The code can be compiled as follows:
g++ -Wall -I/opt/local/include -L/opt/local/lib -lgit2 -o test git.cpp
Below is the output of running the compiled binary:
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: file1
new file: file2
Once the index is updated
create a tree from it through git_index_write_tree()
create a commit that references this tree through git_commit_create_v()
See this end to end test which performs the equivalent of the following
$ echo "test" > test.txt
$ git add .
$ git commit -m "Initial commit"

Calling fgets() on popen() of 'ssh' is flushing the beginning of stdin of the calling process (ptty issue)

I have now whittled this down to a minimal test case. Thus far I have been able to determine that this is an issue related to pseudo-terminals which come about with the pipe of ssh. Adding the '-t -t' to the ssh call improved things, in that now, it takes a second call to fgets() to cause the issue. I suspect that the stderr output of the ssh command somehow works into the issue, for now I have redirected stderr to stdout in the ssh code to execute. I do wonder if the "tcgetattr: Invalid argument" error is part of the problem, but am not sure how to get rid of that. It seems to come from the -t -t being present. I believe the -t -t is moving in the right direction, but I have to set up the pseudo terminal for stderr somehow and perhaps the test will work properly?
The Makefile:
test:
gcc -g -DBUILD_MACHINE='"$(shell hostname)"' -c -o test.o test.c
gcc -g -o test test.o
.PHONY: clean
clean:
rm -rf test.o test
The test.c source file:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
const unsigned int bufSize = 32;
char buf1[bufSize];
char buf2[bufSize];
int ssh = argv[1][0] == 'y';
const char *cmd = ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1" : "ls";
FILE *fPtr = popen(cmd, "r");
if (fPtr == NULL) {
fprintf(stderr,"Unable to spawn command.\n");
perror("popen(3)");
exit(1);
}
printf("Command: %s\n", cmd);
if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) {
printf("First result: %s\n", buf2);
if (feof(fPtr) == 0 && fgets(buf2, bufSize, fPtr) != NULL) {
printf("Second result: %s\n", buf2);
int nRead = read(fileno(stdin), buf1, bufSize);
if (nRead == 0) {
printf("???? popen() of ssh consumed the beginning of stdin ????\n");
} else if (nRead > 0) {
if (strncmp("The quick brown fox jumped", buf1, 26) != 0) {
printf("??? Failed ???\n");
} else {
printf("!!!!!!! Without ssh popen() did not consume stdin !!!!!!!\n");
}
}
}
}
}
This shows it running the passing way:
> echo "The quick brown fox jumped" | ./test n
Command: ls
First result: ARCH.linux_26_i86
Second result: Makefile
!!!!!!! Without ssh popen() did not consume stdin !!!!!!!
This shows it running the failing way:
> echo "The quick brown fox jumped" | ./test y
Command: ssh -t -t hostname "ls" 2>&1
First result: tcgetattr: Invalid argument
Second result: %backup%~ gmon.out
???? popen() of ssh consumed the beginning of stdin ????
Okay, I have got this working finally. The secret was to supply /dev/null as the input to my ssh command as follows from the test case above:
const char *cmd
= ssh ? "ssh -t -t " BUILD_MACHINE " \"ls\" 2>&1 < /dev/null" : "ls";
However, while the code works correctly, I get a nasty message which apparently I can ignore for my purposes (although I'd like to make the message go away):
tcgetattr: Inappropriate ioctl for device

Command line tool to dump Windows DLL version?

I need a command line tool to dump standard Windows DLL version info so I can process it by means of a bash script (Cygwin).
As a Java developer I am not very used to Microsoft development tools (though I have a little bit of experience with Microsoft Visual Embedded C++ 4.0 and Microsoft Visual Basic 6.0).
The appropriate tool seems to be mt.exe, as stated on SO. However the only chance I have found to get this little application is to download a 1.29 GB ISO of the Windows SDK for Windows Server 2008 and .NET Framework. I can not believe this is the only way to do it.
I have also found a little application on the Internet called PEView, but it displays too much (and useless in my case) information and it is not a command line application.
Standard objdump bundled inside Cygwin can also dump some information about the DLL files, but I can not see the option to dump DLL version. Note that MajorImageVersion, MinorImageVersion and other fields dumped by this tool (with -p option) are not related to own DLL version.
Any alternatives about what to do? Maybe I missed some important objdump option? Is mt.exe my only choice? If this is the case, is it possible to get it separately from Windows SDK?
You can use PowerShell to get the information you want.
(Get-Item C:\Path\To\MyFile.dll).VersionInfo
By default this will display ProductVersion and FileVersion
But the full VERSIONINFO is available. I.e. to return Comments
(Get-Item C:\Path\To\MyFile.dll).VersionInfo.Comments
Use Microsoft Sysinternals Sigcheck.
This sample outputs just the version:
sigcheck -q -n foo.dll
Unpacked sigcheck.exe is only 228 KB.
You can write a VBScript script to get the file version info:
VersionInfo.vbs
set args = WScript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetFileVersion(args(0))
Wscript.Quit
You can call this from the command line like this:
cscript //nologo VersionInfo.vbs C:\Path\To\MyFile.dll
C:\>wmic datafile where name="C:\\Windows\\System32\\kernel32.dll" get version
Version
6.1.7601.18229
You can also look at filever.exe, which can be downloaded as part of the Windows XP SP2 Support Tools package - only 4.7MB of download.
or you can build one yourself. Open VS, create a new console application. Create a simple project with no ATL or MFC support, leave the stdafx option checked but do not check 'empty project' and call it VersionInfo.
You'll get a simple project with 2 files: VersionInfo.cpp and VersionInfo.h
Open the cpp file and paste the following into it, then compile. You'll be able to run it, first argument is the full filename, it'll print out "Product: 5.6.7.8 File: 1.2.3.4" based on the Version resource block. If there's no version resource it'll return -1, otherwise 0.
Compiles to an 8k binary using the dll CRT, 60k with everything linked statically (set in the C++ options, change "Code Generation page, Runtime options" to "/MT")
HTH.
PS. If you don't want to use Visual Studio, it'll still compile using any c++ compiler (fingers crossed), but you'll almost certainly have to change the #pragma - just specify that lib in the linker settings instead, the pragma's just a shorthand to automatically link with that library.
// VersionInfo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#pragma comment(lib, "version.lib")
int _tmain(int argc, _TCHAR* argv[])
{
DWORD handle = 0;
DWORD size = GetFileVersionInfoSize(argv[1], &handle);
BYTE* versionInfo = new BYTE[size];
if (!GetFileVersionInfo(argv[1], handle, size, versionInfo))
{
delete[] versionInfo;
return -1;
}
// we have version information
UINT len = 0;
VS_FIXEDFILEINFO* vsfi = NULL;
VerQueryValue(versionInfo, L"\\", (void**)&vsfi, &len);
WORD fVersion[4], pVersion[4];
fVersion[0] = HIWORD(vsfi->dwFileVersionMS);
fVersion[1] = LOWORD(vsfi->dwFileVersionMS);
fVersion[2] = HIWORD(vsfi->dwFileVersionLS);
fVersion[3] = LOWORD(vsfi->dwFileVersionLS);
pVersion[0] = HIWORD(vsfi->dwProductVersionMS);
pVersion[1] = LOWORD(vsfi->dwProductVersionMS);
pVersion[2] = HIWORD(vsfi->dwProductVersionLS);
pVersion[3] = LOWORD(vsfi->dwProductVersionLS);
printf("Product: %d.%d.%d.%d File: %d.%d.%d.%d\n",
pVersion[0], pVersion[1],
pVersion[2], pVersion[3],
fVersion[0], fVersion[1],
fVersion[2], fVersion[3]);
delete[] versionInfo;
return 0;
}
Using Powershell it is possible to get just the Version string, i.e. 2.3.4 from any dll or exe with the following command
(Get-Item "C:\program files\OpenVPN\bin\openvpn.exe").VersionInfo.ProductVersion
Tested on Windows 10
The listdlls tools from Systernals might do the job: http://technet.microsoft.com/en-us/sysinternals/bb896656.aspx
listdlls -v -d mylib.dll
This function returns the ntfs Windows file details for any file using Cygwin bash (actual r-click-properties-info) to the term
Pass the files path to finfo(), can be unix path, dos path, relative or absolute. The file is converted into an absolute nix path, then checked to see if it is in-fact a regular/existing file. Then converted into an absolute windows path and sent to "wmic". Then magic, you have windows file details right in the terminal. Uses: cygwin, cygpath, sed, and awk. Needs Windows WMI "wmic.exe" to be operational. The output is corrected for easy...
$ finfo notepad.exe
$ finfo "C:\windows\system32\notepad.exe"
$ finfo /cygdrive/c/Windows/System32/notepad.exe
$ finfo "/cygdrive/c/Program Files/notepad.exe"
$ finfo ../notepad.exe
finfo() {
[[ -e "$(cygpath -wa "$#")" ]] || { echo "bad-file"; return 1; }
echo "$(wmic datafile where name=\""$(echo "$(cygpath -wa "$#")" | sed 's/\\/\\\\/g')"\" get /value)" |\
sed 's/\r//g;s/^M$//;/^$/d' | awk -F"=" '{print $1"=""\033[1m"$2"\033[0m" }'
}
There is an command line application called "ShowVer" at CodeProject:
ShowVer.exe command-line VERSIONINFO display program
As usual the application comes with an exe and the source code (VisualC++ 6).
Out outputs all the meta data available:
On a German Win7 system the output for user32.dll is like this:
VERSIONINFO for file "C:\Windows\system32\user32.dll": (type:0)
Signature: feef04bd
StrucVersion: 1.0
FileVersion: 6.1.7601.17514
ProductVersion: 6.1.7601.17514
FileFlagsMask: 0x3f
FileFlags: 0
FileOS: VOS_NT_WINDOWS32
FileType: VFT_DLL
FileDate: 0.0
LangID: 040704B0
CompanyName : Microsoft Corporation
FileDescription : Multi-User Windows USER API Client DLL
FileVersion : 6.1.7601.17514 (win7sp1_rtm.101119-1850)
InternalName : user32
LegalCopyright : ® Microsoft Corporation. Alle Rechte vorbehalten.
OriginalFilename : user32
ProductName : Betriebssystem Microsoft« Windows«
ProductVersion : 6.1.7601.17514
Translation: 040704b0
For some DLLs I found version info manually with objdump in .rsrc. With objdump -s -j .rsrc zlib1.dll:
zlib1.dll: file format pei-x86-64
Contents of section .rsrc:
62e9e000 00000000 00000000 00000000 00000100 ................
62e9e010 10000000 18000080 00000000 00000000 ................
62e9e020 00000000 00000100 01000000 30000080 ............0...
62e9e030 00000000 00000000 00000000 00000100 ................
62e9e040 09040000 48000000 58e00100 34030000 ....H...X...4...
62e9e050 00000000 00000000 34033400 00005600 ........4.4...V.
62e9e060 53005f00 56004500 52005300 49004f00 S._.V.E.R.S.I.O.
62e9e070 4e005f00 49004e00 46004f00 00000000 N._.I.N.F.O.....
62e9e080 bd04effe 00000100 02000100 00000b00 ................
62e9e090 02000100 00000b00 3f000000 00000000 ........?.......
62e9e0a0 04000000 02000000 00000000 00000000 ................
62e9e0b0 00000000 94020000 01005300 74007200 ..........S.t.r.
62e9e0c0 69006e00 67004600 69006c00 65004900 i.n.g.F.i.l.e.I.
62e9e0d0 6e006600 6f000000 70020000 01003000 n.f.o...p.....0.
62e9e0e0 34003000 39003000 34004500 34000000 4.0.9.0.4.E.4...
62e9e0f0 64001e00 01004600 69006c00 65004400 d.....F.i.l.e.D.
62e9e100 65007300 63007200 69007000 74006900 e.s.c.r.i.p.t.i.
62e9e110 6f006e00 00000000 7a006c00 69006200 o.n.....z.l.i.b.
62e9e120 20006400 61007400 61002000 63006f00 .d.a.t.a. .c.o.
62e9e130 6d007000 72006500 73007300 69006f00 m.p.r.e.s.s.i.o.
62e9e140 6e002000 6c006900 62007200 61007200 n. .l.i.b.r.a.r.
62e9e150 79000000 2e000700 01004600 69006c00 y.........F.i.l.
62e9e160 65005600 65007200 73006900 6f006e00 e.V.e.r.s.i.o.n.
62e9e170 00000000 31002e00 32002e00 31003100 ....1...2...1.1.
62e9e180 00000000 34000a00 01004900 6e007400 ....4.....I.n.t.
62e9e190 65007200 6e006100 6c004e00 61006d00 e.r.n.a.l.N.a.m.
62e9e1a0 65000000 7a006c00 69006200 31002e00 e...z.l.i.b.1...
62e9e1b0 64006c00 6c000000 7c002c00 01004c00 d.l.l...|.,...L.
62e9e1c0 65006700 61006c00 43006f00 70007900 e.g.a.l.C.o.p.y.
62e9e1d0 72006900 67006800 74000000 28004300 r.i.g.h.t...(.C.
62e9e1e0 29002000 31003900 39003500 2d003200 ). .1.9.9.5.-.2.
62e9e1f0 30003100 37002000 4a006500 61006e00 0.1.7. .J.e.a.n.
62e9e200 2d006c00 6f007500 70002000 47006100 -.l.o.u.p. .G.a.
62e9e210 69006c00 6c007900 20002600 20004d00 i.l.l.y. .&. .M.
62e9e220 61007200 6b002000 41006400 6c006500 a.r.k. .A.d.l.e.
62e9e230 72000000 3c000a00 01004f00 72006900 r...<.....O.r.i.
62e9e240 67006900 6e006100 6c004600 69006c00 g.i.n.a.l.F.i.l.
62e9e250 65006e00 61006d00 65000000 7a006c00 e.n.a.m.e...z.l.
62e9e260 69006200 31002e00 64006c00 6c000000 i.b.1...d.l.l...
62e9e270 2a000500 01005000 72006f00 64007500 *.....P.r.o.d.u.
62e9e280 63007400 4e006100 6d006500 00000000 c.t.N.a.m.e.....
62e9e290 7a006c00 69006200 00000000 32000700 z.l.i.b.....2...
62e9e2a0 01005000 72006f00 64007500 63007400 ..P.r.o.d.u.c.t.
62e9e2b0 56006500 72007300 69006f00 6e000000 V.e.r.s.i.o.n...
62e9e2c0 31002e00 32002e00 31003100 00000000 1...2...1.1.....
62e9e2d0 78003000 01004300 6f006d00 6d006500 x.0...C.o.m.m.e.
62e9e2e0 6e007400 73000000 46006f00 72002000 n.t.s...F.o.r. .
62e9e2f0 6d006f00 72006500 20006900 6e006600 m.o.r.e. .i.n.f.
62e9e300 6f007200 6d006100 74006900 6f006e00 o.r.m.a.t.i.o.n.
62e9e310 20007600 69007300 69007400 20006800 .v.i.s.i.t. .h.
62e9e320 74007400 70003a00 2f002f00 77007700 t.t.p.:././.w.w.
62e9e330 77002e00 7a006c00 69006200 2e006e00 w...z.l.i.b...n.
62e9e340 65007400 2f000000 44000000 01005600 e.t./...D.....V.
62e9e350 61007200 46006900 6c006500 49006e00 a.r.F.i.l.e.I.n.
62e9e360 66006f00 00000000 24000400 00005400 f.o.....$.....T.
62e9e370 72006100 6e007300 6c006100 74006900 r.a.n.s.l.a.t.i.
62e9e380 6f006e00 00000000 0904e404 00000000 o.n.............
and one way with makecab:
; #echo off
;;goto :end_help
;;setlocal DsiableDelayedExpansion
;;;
;;;
;;; fileinf /l list of full file paths separated with ;
;;; fileinf /f text file with a list of files to be processed ( one on each line )
;;; fileinf /? prints the help
;;;
;;:end_help
; REM Creating a Newline variable (the two blank lines are required!)
; set NLM=^
; set NL=^^^%NLM%%NLM%^%NLM%%NLM%
; if "%~1" equ "/?" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; if "%~2" equ "" type "%~f0" | find ";;;" | find /v "find" && exit /b 0
; setlocal enableDelayedExpansion
; if "%~1" equ "/l" (
; set "_files=%~2"
; echo !_files:;=%NL%!>"%TEMP%\file.paths"
; set _process_file="%TEMP%\file.paths"
; goto :get_info
; )
; if "%~1" equ "/f" if exist "%~2" (
; set _process_file="%~2"
; goto :get_info
; )
; echo incorect parameters & exit /b 1
; :get_info
; set "file_info="
; makecab /d InfFileName=%TEMP%\file.inf /d "DiskDirectory1=%TEMP%" /f "%~f0" /f %_process_file% /v0>nul
; for /f "usebackq skip=4 delims=" %%f in ("%TEMP%\file.inf") do (
; set "file_info=%%f"
; echo !file_info:,=%nl%!
; )
; endlocal
;endlocal
; del /q /f %TEMP%\file.inf 2>nul
; del /q /f %TEMP%\file.path 2>nul
; exit /b 0
.set DoNotCopyFiles=on
.set DestinationDir=;
.set RptFileName=nul
.set InfFooter=;
.set InfHeader=;
.Set ChecksumWidth=8
.Set InfDiskLineFormat=;
.Set Cabinet=off
.Set Compress=off
.Set GenerateInf=ON
.Set InfDiskHeader=;
.Set InfFileHeader=;
.set InfCabinetHeader=;
.Set InfFileLineFormat=",file:*file*,date:*date*,size:*size*,csum:*csum*,time:*time*,vern:*ver*,vers:*vers*,lang:*lang*"
example output (it has a string version which is a small addition to wmic method :) ):
c:> fileinfo.bat /l C:\install.exe
file:install.exe
date:11/07/07
size:562688
csum:380ef239
time:07:03:18a
vern:9.0.21022.8
vers:9.0.21022.8 built by: RTM
lang:1033
and one more Using shell.application and hybrid batch\jscript.Here's tooptipInfo.bat :
#if (#X)==(#Y) #end /* JScript comment
#echo off
rem :: the first argument is the script name as it will be used for proper help message
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%
#if (#X)==(#Y) #end JScript comment */
//////
FSOObj = new ActiveXObject("Scripting.FileSystemObject");
var ARGS = WScript.Arguments;
if (ARGS.Length < 1 ) {
WScript.Echo("No file passed");
WScript.Quit(1);
}
var filename=ARGS.Item(0);
var objShell=new ActiveXObject("Shell.Application");
/////
//fso
ExistsItem = function (path) {
return FSOObj.FolderExists(path)||FSOObj.FileExists(path);
}
getFullPath = function (path) {
return FSOObj.GetAbsolutePathName(path);
}
//
//paths
getParent = function(path){
var splitted=path.split("\\");
var result="";
for (var s=0;s<splitted.length-1;s++){
if (s==0) {
result=splitted[s];
} else {
result=result+"\\"+splitted[s];
}
}
return result;
}
getName = function(path){
var splitted=path.split("\\");
return splitted[splitted.length-1];
}
//
function main(){
if (!ExistsItem(filename)) {
WScript.Echo(filename + " does not exist");
WScript.Quit(2);
}
var fullFilename=getFullPath(filename);
var namespace=getParent(fullFilename);
var name=getName(fullFilename);
var objFolder=objShell.NameSpace(namespace);
var objItem=objFolder.ParseName(name);
//https://msdn.microsoft.com/en-us/library/windows/desktop/bb787870(v=vs.85).aspx
WScript.Echo(fullFilename + " : ");
WScript.Echo(objFolder.GetDetailsOf(objItem,-1));
}
main();
used against cmd.exe :
C:\Windows\System32\cmd.exe :
File description: Windows Command Processor
Company: Microsoft Corporation
File version: 6.3.9600.16384
Date created: ?22-?Aug-?13 ??13:03
Size: 347 KB