CreateProcess weird behavior with files without extension - winapi

I have noticed this behavior:
There are 2 executable files in the current dir, named 'somefile' and 'somefile.abc'.
CreateProcessA(NULL, "somefile", ...) - fails with error code 2 (ERROR_FILE_NOT_FOUND)
CreateProcessA(NULL, "somefile.abc", ...) - works
CreateProcessA(NULL, ".\\somefile", ...) - works
CreateProcessA(NULL, ".\\somefile.abc", ...) - works
So, it looks like the ".\" is mandatory if and only if the file doesn't have an extension.
Is there a logic behind this behavior?

From MSDN:
If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended.
I don't know if the documented behavior should be called "weird".

Related

Why does cmd DIR search include files that start with the 3 searched letters but then differ?

If in a directory I have two files, test.pro and test.properties, and I run dir /s *.pro to find all files with the .pro extension, it lists both files. However, when I run dir /s *.pr, it lists neither. Why does searching for a three-letter file extension list files with extensions that start with the three letters? How can I search for ONLY .pro files using dir?
The command DIR lets the file system search for file system entries (file names, directory names, reparse points (links)) matching the wildcard pattern *.pro in long name or in short 8.3 name on short name management also enabled for the file system of current drive.
The short file name of test.pro is TEST.PRO.
The short file name of test.properties is TEST~1.PRO.
Therefore the wildcard pattern *.pro matches test.pro and TEST~1.PRO displayed with long file name test.properties.
The wildcard pattern *.pr does not match with the two file names because of the file extension is pro respectively properties and not just pr. The wildcard pattern *.pr? would also find the file names test.pro and TEST~1.PRO displayed with long file name test.properties.
There can be used %SystemRoot%\System32\where.exe /R . *.pro to find recursively in current directory and all its subdirectories files with file extension .pro not matching file names with a longer file extension beginning with pro because of WHERE applies the wildcard pattern only on long file names.
DIR and also FOR use the Windows file I/O function which directly searches with the wildcard pattern *.pro for suitable file system entries. WHERE uses the Windows file I/O function to search for * to get a list of long names of all file system entries and then applies the wildcard pattern itself on each string returned by the file system. For that reason the usage of the wildcard pattern *.pro returns a positive result only on test.pro and not on test.properties on using WHERE.

Unable to load/require file from Lua running from Atom in Windows

I'm trying to use Atom to run a Lua script. However, when I try to load files via the require() command, it always says it's unable to locate them. The files are all in the same folder. For example, to load utils.lua I have tried
require 'utils'
require 'utils.lua'
require 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua'
require 'D:\\Users\\Mike\\Dropbox\\Lua Modeling\\utils.lua'
require 'D:/Users/Mike/Dropbox/Lua Modeling/utils.lua'
I get errors like
Lua: D:\Users\Mike\Dropbox\Lua Modeling\main.lua:12: module 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua' not found:
no field package.preload['D:\Users\Mike\Dropbox\Lua Modeling\utils.lua']
no file '.\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'
no file 'D:\Program Files (x86)\Lua\5.1\lua\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'
no file 'D:\Program Files (x86)\Lua\5.1\lua\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua\init.lua'
no file 'D:\Program Files (x86)\Lua\5.1\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'
The messages says on the first line that 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua' was not found, even though that is the full path of the file. What am I doing wrong?
Thanks.
The short answer
You should be able to load utils.lua by using the following code:
require("utils")
And by starting your program from the directory that utils.lua is in:
cd "D:\Users\Mike\Dropbox\Lua Modeling"
lua main.lua
The long answer
To understand what is going wrong here, it is helpful to know a little bit about how require works. The first thing that require does is to search for the module in the module path. From Programming in Lua chapter 8.1:
The path used by require is a little different from typical paths. Most programs use paths as a list of directories wherein to search for a given file. However, ANSI C (the abstract platform where Lua runs) does not have the concept of directories. Therefore, the path used by require is a list of patterns, each of them specifying an alternative way to transform a virtual file name (the argument to require) into a real file name. More specifically, each component in the path is a file name containing optional interrogation marks. For each component, require replaces each ? by the virtual file name and checks whether there is a file with that name; if not, it goes to the next component. The components in a path are separated by semicolons (a character seldom used for file names in most operating systems). For instance, if the path is
?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
then the call require"lili" will try to open the following files:
lili
lili.lua
c:\windows\lili
/usr/local/lua/lili/lili.lua
Judging from your error message, your Lua path seems to be the following:
.\?.lua;D:\Program Files (x86)\Lua\5.1\lua\?.lua;D:\Program Files (x86)\Lua\5.1\lua\?\init.lua;D:\Program Files (x86)\Lua\5.1\?.lua
To make that easier to read, here are each the patterns separated by line breaks:
.\?.lua
D:\Program Files (x86)\Lua\5.1\lua\?.lua
D:\Program Files (x86)\Lua\5.1\lua\?\init.lua
D:\Program Files (x86)\Lua\5.1\?.lua
From this list you can see that when calling require
Lua fills in the .lua extension for you
Lua fills in the rest of the file path for you
In other words, you should just specify the module name, like this:
require("utils")
Now, Lua also needs to know where the utils.lua file is. The easiest way is to run your program from the D:\Users\Mike\Dropbox\Lua Modeling folder. This means that when you run require("utils"), Lua will expand the first pattern .\?.lua into .\utils.lua, and when it checks that path it will find the utils.lua file in the current directory.
In other words, running your program like this should work:
cd "D:\Users\Mike\Dropbox\Lua Modeling"
lua main.lua
An alternative
If you can't (or don't want to) change your working directory to run the program, you can use the LUA_PATH environment variable to add new patterns to the path that require uses to search for modules.
set LUA_PATH=D:\Users\Mike\Dropbox\Lua Modeling\?.lua;%LUA_PATH%;
lua "D:\Users\Mike\Dropbox\Lua Modeling\main.lua"
There is a slight trick to this. If the LUA_PATH environment variable already exists, then this will add your project's folder to the start of it. If LUA_PATH doesn't exist, this will add ;; to the end, which Lua fills in with the default path.

Open file from same directory

Ok so with siriproxy it my lib folder along with the rb file for the plugin I have created a myconfig.yml file so I can change certain settings by writing to that file.
I have been able to write to the file but only if I include the full path all the way from the home directory down.
But is there not a way to open the file from the same directory i am in? I have tried every path combination I can think of.
There has to be one i am missing
If you use the following in your ruby file, you should get the absolute path where it is
File.expand_path(__FILE__)
From doc __FILE__
The name of the file currently being executed, including path relative to the directory where the application was started up (or the current directory, if it has been changed)
From doc File.expand_path
Converts a pathname to an absolute pathname.
As you probably want the directory, you should use File.dirname(__FILE__), so the path of your file myconfig.yml should be obtained with
File.join(File.expand_path(File.dirname(__FILE__)), 'myconfig.yml')
In more recent Ruby (>=2.0.0), you can use __dir__ (from Archonic's comment):
Returns the canonicalized absolute path of the directory of the file from which this method is called. It means symlinks in the path is resolved. If FILE is nil, it returns nil. The return value equals to File.dirname(File.realpath(FILE)).

Include File that is not in the same directory as script

I have a NSIS script that is attempting to include a .NSI file that sits in a different folder.
My Problem: When I go to compile my script I get the compile error !include: could not find: "../Utilities.nsi". This file exists and is in the correct location I am specifying(in the parent directory - one step back).
How can I include a file that sits in another directory? I hope its possible.
!include "../Utilities.nsi" # include error: '!include: could not find: "../Utilities.nsi"'
InstallDir "abc"
Name "def"
OutFile "def.exe"
Section
DetailPrint "Hello World"
SectionEnd
The manual says this about !include:
This command will include 'file' as if it was part of the original
script. Note that if a file is included in another directory, the
current directory is still where the script was compiled from (not
where the included file resides). If the compiler can't find the file
it will look for it in every include directory. See !addincludedir for
more information. If the /nonfatal switch is used and no files are
found, a warning will be issued instead of an error."
Also, the examples in the manual do not use quotation marks -- did you try
removing them? Also, "/" => "\".

How can I rename a file with Ruby that includes a / character?

I've written a little Ruby command line app that I use to keep TV Shows organized on my Mac harddrive. Given the nature of TV episode titles there are episodes which include the / character.
Being on a Mac, the filesystem actually allows me writing this file and if I manually rename the file with the / character in it everything is fine.
The moment Ruby's File.rename runs in my script however I simply get a No such file or directory error because Ruby tries to read the / in the filename as a folder which should exist.
Here is an example:
Output path is /TV/Showname/Season 1/Showname - 1x07 - 5/1.mp4
Now rather than looking for the folder /Showname - 1x07 - 5/ and write to a 1.mp4 file inside of it, how can I tell ruby to simply take the filename (Showname - 1x07 - 5/1.mp4) and write it into the Season 1 folder as is?
Thanks for reading.
A weird one this, but because the backslash is used as a file-separator, it is converted to a colon in the filename used by Ruby. So to rename your file, replace the forward slash in the name with a colon.
So you would write something like:
File.rename("Showname - 1x07 - 5:1.mp4", "/TV/Showname/Season 1/Showname - 1x07 - 5:1.mp4")

Resources