AWS CLI file extension association warning on Windows - windows

Using aws cli with python 3 on Windows, always getting a warning, but the program runs well after this message.
For example:
>>> aws --version --debug
Не найдено сопоставление для расширения имени файла .py.
aws-cli/1.15.83 Python/3.6.0 Windows/7 botocore/1.10.82
(vaguely -' Cannot find association for filename extension .py')
Any idea which part of aws scripts issues this warning and how to fix it? At what part does aws use Windows call?

As #Evgeny describes in Windows after install AWS CLI the file aws.cmd has this line that calls the command assoc and produces the warning:
for /f "tokens=2 delims==" %%i in ('assoc .py') do (
The command assoc .py shows if there is an association to python files in Windows. If you don't have a python executable associated with *.py files in your main command line (no in environments of Anaconda).
You can test that opening a command line window and try to run a simple script in a folder this way:
>test.py
If you get an error and you like to remove the warning you have to make a new association for python files, with one of this options.
By command line (as administrator)
assoc .py=py_auto_file
ftype py_auto_file="C:\Anaconda3\python.exe" "%1" %*
By GUI changing Defaults apps
Right clic any file with extension *.py and select properties, and select a program that manage this file, for example in "C:\Anaconda3\python.exe" or change the default app.
In Windows 10 you can follow this sequence "Start menu, select Settings > Apps > Default apps"

you have to meet the dependency with: https://www.python.org/downloads/
so that windows could have something to register file-type .py with.
or you'd have to register .py to open with python3.exe (or alike).

I managed to get feedback on a issue on Github. Basically, there is a one line change that can supress the warning.
In aws.cmd instead of:
for /f "tokens=2 delims==" %%i in ('assoc .py') do (
use:
for /f "tokens=2 delims==" %%i in ('assoc .py 2^> nul') do (
This diverts warnings to null. There is also a
pull request
with this suggested change, but it was not mergerged to code unfortunately.
Anyone experiencing this problem can change a local file aws.cmd as <your python directory>/Scripts folder.

Related

Self-extracting executable do not recognize an existing command in System32

I'm developing a stack of Windows Batch scripts (.bat) which are subsequently converted to self-extracting executabled.
Currently I'm facing a really strange problem. I create this self-extracting executable, which, after extracting all the files, will launch the main wrapper, (SETUP.bat). The whole stack of the scripts gets running and everything goes right until some point.
One part of the stack has to commit some files with UWFMGR, and I have a loop for like this:
SETLOCAL EnableDelayedExpansion
FOR /F usebackq "tokens=*" %%F IN ("DIR /S /B /A-D") DO (
uwfmgr file commit "%%F"
)
If I run the executable, the execution of the stack does not recognize the command UWFMGR
I stopped the execution of the script, and went with the same CMD, (which it's launched by the executable), to the System32 folder to check if the UWFMGR is there. I did a DIR "uwfmgr.exe", and it's not there. But if I go with another CMD (a new one) the command is there. I even went with a file explorer to verify it and it's completely there but somehow the CMD which it's being launched by the executable cannot recognize it.
I have tried to specify the whole path in the loop like this "C:\Windows\System32\UWFMGR.exe" and it doesn't even work.
The funny thing is that if run this script it works and commits all the files required.
SETLOCAL EnableDelayedExpansion
FOR /F usebackq "tokens=*" %%F IN ("DIR /S /B /A-D") DO (
uwfmgr file commit "%%F"
)
Does anyone have any idea of why this is happening?
Check the output of the command and the errorlevel, it's 9009 (the file/command does not exist)
Do an echo to check the command I'm passing through the loop, the command is OK
I expect the executable to do the whole stack and commit the files but the executable does not recognize UWFMGR command. I use other commands in my stack and I didn't have any problem.
64-bit Windows has two system32 folders. Windows\system32 is the real folder used by 64-bit applications. 32-bit applications are automatically redirected to Windows\Syswow64 when they access system32. There is a backdoor you can use to access the real system32 folder.
You should use if exist and set to find and store a usable path:
#echo off
set app=%windir%\system32\UWFMGR.exe
set appalt=%windir%\sysnative\UWFMGR.exe
if not exist "%app%" if exist "%appalt%" set app=%appalt%
echo.I will use %app%
UWFMGR seems to be an optional feature and is probably not present by default on most machines.
I solved it after finding out the exe was created as 32bits. I had to create as 64 bits in order to make it work. Now the executable is able to use the UWFMGR.
Thank you everyone for your answers and have a nice day.
I'm using this 7sfx module, just in case anyone's wondering: "7zsd_All_x64.sfx"

Access system32 from VisualStudio 2019 build script

In a post build step i want check if OpenSSH.Client and OpenSSH.Server is installed and install it if it is not there. Checking the installed features with Powershell needs administrative privileges.
Therefore i test the existence of the relevant OpenSSH commands with the following code (extract of long script)
SET /a res=0
SET /a three=3
%windir%\system32\OpenSSH\ssh-keygen.exe /?
echo Errorlevel %ERRORLEVEL%
IF %ERRORLEVEL%==%three% (SET /a res=%res%+1)
%windir%\system32\OpenSSH\ssh-keyscan.exe /?
echo Errorlevel %ERRORLEVEL%
IF %ERRORLEVEL%==%three% (SET /a res=%res%+1)
SET /a check=0
IF %res% == %check% (
echo already installed
goto skipopenSSH
)
echo installation
:skipopenSSH
By checking the existence of the commands no admin privileges are necessary for the check so a normal build will not cause a administrative popup.
On cmd.exe it works fine, but as a post build step in Visual Studio both commands in %windir%\systrem32\OpenSSH are not found, although the variable is expanded to the same c:\Windows\System32\OpenSSH\*.exe as if executed on commandline.
After trying the different find mechanisms which all fail i made a test batch file C:\Windows\System32\OpenSSH\ssh-keyscan.exe /?
which leads to a file not found error if executed as a post build step. So the real question should be: Modifies the visual studio build step commandline the path?
The directory OpenSSH exists in directory %SystemRoot%\System32 with the files ssh-keygen.exe and ssh-keyscan.exe depending on version of Windows 10. The directory %SystemRoot%\System32 is for 64-bit applications on 64-bit Windows. But Visual Studio is a 32-bit application and for that reason 32-bit Windows command processor in directory %SystemRoot%\SysWOW64 is executed to process the batch file with the commands to execute as post build step.
Microsoft documented with WOW64 Implementation Details, File System Redirector and Registry Keys Affected by WOW64 and other documentation pages how Windows on Windows 64 works.
All file system accesses to %windir%\system32\OpenSSH in the batch file processed by 32-bit %SystemRoot%\SysWOW64\cmd.exe being started by 32-bit Visual Studio results in the approach to access %SystemRoot%\SysWOW64\OpenSSH which does not exist at all. There is no subdirectory OpenSSH in Windows system directory for 32-bit applications.
One solution would be using the following code for the batch file executed as post build step.
rem This simple check is for 32-bit Windows and for 64-bit Windows with batch
rem file executed in 64-bit environment by 64-bit Windows command processor.
set FolderSSH=%SystemRoot%\System32\OpenSSH
if exist %FolderSSH%\ssh-keygen.exe if exist %FolderSSH%\ssh-keyscan.exe goto UseOpenSSH
rem This check is for 64-bit Windows with batch file executed
rem in 32-bit environment by 32-bit Windows command processor.
if exist %SystemRoot%\Sysnative\cmd.exe set FolderSSH=%SystemRoot%\Sysnative\OpenSSH
if exist %FolderSSH%\ssh-keygen.exe if exist %FolderSSH%\ssh-keyscan.exe goto UseOpenSSH
rem Search entire system drive on machines without Windows 10 or with older
rem versions of Windows 10 with OpenSSH not installed at all by default.
for /F "delims=" %%I in ('%SystemRoot%\System32\where.exe /R %SystemDrive%\ ssh-keygen.exe 2^>nul') do (
if exist "%%~dpIssh-keyscan.exe" for %%J in ("%%~dpI.") do set "FolderSSH=%%~fJ" & goto UseOpenSSH
)
echo ERROR: ssh-keygen.exe AND ssh-keyscan.exe not found.
rem More code to handle this use case.
goto :EOF
:UseOpenSSH
echo Found ssh-keygen and ssh-keyscan in: "%FolderSSH%"
rem More code to handle this use case with existing SSH tools.
The remarks explain most of the code. The inner FOR loop is used to get the full qualified name of the directory containing ssh-keygen.exe and ssh-keyscan.exe without backslash at end of the folder path to have FolderSSH defined always without a backlash at end for further usage in the batch file.
Please note that it is safe to use %FolderSSH%\ssh-keygen.exe and %FolderSSH%\ssh-keyscan.exe without surrounding " at beginning of the batch script as it is impossible that %FolderSSH% expands to a folder path containing a space or one of these characters &()[]{}^=;!'+,`~.
But "%FolderSSH%\ssh-keygen.exe" and "%FolderSSH%\ssh-keyscan.exe" must be used on the command lines below the label UseOpenSSH because it could happen that WHERE was used to find the two executables anywhere on system drive and for that reason %FolderSSH% could expand now to a folder path containing a space or a character with a special meaning for Windows command processor outside a double quoted argument string.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
for /?
goto /?
if /?
rem /?
set /?
where /?
Read also the Microsoft article about Using command redirection operators for an explanation of 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded where command line with using a separate command process started in background with %ComSpec% /c and the command line between ' appended as additional arguments on which 2^>nul became already 2>nul.
The following idea also uses the where.exe command, as mentioned in the comments. This one will search the system drive for ssh-keyscan.exe, and if found will ensure that ssh-keygen.exe is also located there. If both are located in the same place, then it is considered as already installed:
#Set "dirOpenSSH="
#For /F Delims^= %%G In (
'%__AppDir__%where.exe /R %SystemDrive%\ ssh-keyscan.exe 2^>NUL'
)Do #For /F Delims^= %%H In (
'%__AppDir__%where.exe "%%~dpG.":ssh-keygen.exe 2^>NUL'
)Do #Set "dirOpenSSH=%%~dpH"
#If Defined dirOpenSSH (
Echo OpenSSH is available at %dirOpenSSH%.
%__AppDir__%timeout.exe 3 /NoBreak>NUL
GoTo skipopenSSH
)
#Echo OpenSSH is not available, beginning installation.
#%__AppDir__%timeout.exe 3 >NUL
:skipopenSSH
Please note that where.exe and timeout.exe require a minimum OS version of Windows NT 6.x
As your application is currently a 32-bit one, the console session it is using is not accessing the 64-bit locations. To fix that you could replace %__AppDir__%where.exe, with %SystemRoot%\SysNative\where.exe
It is probably worth mentioning that in the versions of windows-10 with OpenSSH part of the base OS, the location, %SYSTEMROOT%\System32\OpenSSH\, should exist in %PATH%, so you should be able to find your files directly using them:
%__AppDir__%where.exe ssh-keygen.exe
%__AppDir__%where.exe ssh-keyscan.exe
For %I In (ssh-keygen.exe) Do #Echo %~$PATH:I
For %I In (ssh-keyscan.exe) Do #Echo %~$PATH:I
I have found on the systems which have upgraded from an earlier version of Windows, that many of the default locations using C:\Windows were replicated, but using %SYSTEMROOT%/%SystemRoot% instead.
In that state, the Where command and For's %~$PATH: failed to locate some items which did exist and should have been found.
Removing the duplicated items, I removed those which were carried over, (those not using variables), although removing either format seems to have worked fine.
Both where and %~$PATH: were then functioning as intended.

MS-DOS "plugin" system?

Creating a program called Joker.cmd (https://github.com/nightmare-dll/Joker/), and it's basically done. Was basically me testing out github at first and turned into something I wouldn't mind fully releasing.
It's basically done, so I would love to implement a user plugin system. Dir tree is as of rightnow (not synced on github);
data/
-config.cmd
plugins/
- test1.cmd
- test2.cmd
joker.cmd
So then joker.cmd would list both "test1.cmd" and "test2.cmd" and have a
set /p plugin=Plugin name;
start %plugin%.cmd
and then run the specified plugin.
The only issue is how would I get joker.cmd to list only files ending in either .cmd or .bat?
How would I get joker.cmd to list only files ending in either .cmd or .bat?
Add the following lines to joker.cmd to run the plugins automatically:
for /f "tokens=*" %%f in ('dir /b plugins\*.cmd plugins\*.bat') do (
start "" %%f
)
Add the following lines to joker.cmd to prompt for the plugin to run:
dir /b plugins\*.cmd plugins\*.bat
set /p plugin=Plugin name:
start "" plugins\%plugin%
Note:
Always include a TITLE this can be a simple string like "My Script" or just a pair of empty quotes ""
According to the Microsoft documentation, the title is optional, but depending on the other options chosen you can have problems if it is omitted.
Source start
Further Reading
An A-Z Index of the Windows CMD command line - An excellent reference for all things Windows cmd line related.
dir - Display a list of files and subfolders.
for /f - Loop command against the results of another command.
start - Start a program, command or batch script (opens in a new window).

Close all locally opened files in a given directory

I'm trying to add a step to a batch process to make sure all local files have been closed in a specific directory.
Everything I can find keeps pointing me to Net Files and Openfiles, but both of these options only close open files accessed via share (not local).
I've looked at both taskkill and microsoft's handle tool, but from what I can tell this isn't the smartest way to go about this task.
Is there an equivalent to Net Files that will close files opened locally?
Any help would be appreciated.
you might try this with handle on the command line:
for /f "tokens=2 delims=:" %a in ('handle "c:\folder"') do #for /f %b in ("%~a") do #echo handle -c %~b
Remove echo if the output looks good.

Visual Studio macro (-D) from command output

I'm trying to get the output of git describe into my build as a preprocessor define, to use in versioning modules. Unfortunately, it's being a bit contrary (not sure where the issue is).
I had a pre-build event like:
for /f "delims=" %a in ('git describe') do set GITID=%a
which works from the command prompt, but returned code 255 in the build (which caused an error). So I changed it to:
git describe > buildprops_gitid.txt
set /p GITID= < buildprops_gitid.txt
which again, works in command prompt (and doesn't error during build). The file is created with the correct value.
In the preprocessor settings, I then have:
BUILD_TARGETFILE=$(TargetFileName)
BUILD_GITID=$(GITID)
The former works fine, putting the target filename into the file as expected. The latter doesn't work, instead putting an empty string. I suspect this is related to the env var being lost somewhere along the way.
Is there a way to get the output of CLI programs and use that as variables ($(var)) within Visual Studio?
the workaround i found for this was to generate an include file in a pre-build event.
something like the following version.bat script:
#echo off
FOR /F "tokens=*" %%i IN ('call git describe --always') DO echo #define VCSVERSION "%%i" > vcsversion.h
and then add #include "vcsversion.h" in the code.
this is basically the solution i suggested here

Resources