I guess my attempt failed for two reasons:
My programming skills are limited to a few months of on the job coding-retraining before I dropped out, none of that is in VBscript or even in an OOP language and;
I'm a dummy :) }
=======================================================
My original goal was to open a text file (wincmd.ini), do a straight (=unconditional) search and replace on twice (lines 11 and 12), save the same file and close it. This should happen at Windows-startup. I tried to use DOS batch files, but no joy. This VBscript seems to work, but I'm still getting the following error for this code. Please could you advise where it is wrong? Line 9 is "strText = objFile.ReadAll".
error:
Line 9 | Character 1 | Error: Input past end of file | Code: 800A003E |
Source: Microsoft VBScript runtime error.
Const ForReading = 1
Const ForWriting = 2
Const FileIn = "C:\totalcmd852\wincmd.ini"
Const FileOut = "C:\totalcmd852\wincmd.ini" '<== Change to prevent overwrite of original file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(FileIn, ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, "D:\totalcmd852\aWin10.bar", "C:\totalcmd852\aWin7.bar")
strNewText = Replace(strText, "D:\", "C:\")
Set objFile = objFSO.OpenTextFile(FileOut, ForWriting)
objFile.WriteLine strNewText
objFile.Close
What I tried:
I looked at other solutions here and elsewhere, so I did figure out this is clearly, the infamous ReadAll error. It's trying to read something which isn't there. But ...... the problem is, the wincmd.ini-file is TOO, there.
Please refer me to other solutions, and feel free to tell me what obvious thing I missed, but really: NONE of them seemed applicable to me. Then again, I've got very, very, very limited coding experience.
EDIT:
The suggested answer did not fit, because:
For some reason, each time I boot up, the file question is reduced to zero length. This produced the error.
Related
Question about running a custom function in Powershell.
I'm on Windows 10 and I'd like to somehow print my monorepository's directory tree structure excluding node_modules. This is not supported out of the box but requires a custom function to be defined. I found one solution on StackOverflow (https://stackoverflow.com/a/43810460/9654273), which would enable using a command like:
tree -Exclude node_modules -Ascii > tree.txt
The problem is I don't know what to do with the provided source code :D The answer says "add to your $PROFILE, for instance", so I ran notepad $PROFILE in PowerShell, pasted the code snippet there, saved it and tried running the command. It didn't work because I did something wrong. According to the StackOverflow post's comments from anand_v.singh and mklement0 I was still running some other tree command, not the one I just attempted to define.
So how do I use a custom function in PowerShell? Starting point is that source code is on StackOverflow and I don't know where to paste it. Or do you know some other, easier way to print a directory tree on Windows 10 excluding node_modules?
I had the same problem with that function. The issue is the special characters in the hashtable at line 106:
$chars = #{
interior = ('├', '+')[$ndx]
last = ('└', '\')[$ndx] #'
hline = ('─', '-')[$ndx]
vline = ('│', '|')[$ndx]
space = ' '
}
I changed the special characters to ascii as follows:
$chars = #{
interior = ('+', '+')[$ndx]
last = ('\', '\')[$ndx] #'
hline = ('-', '-')[$ndx]
vline = ('|', '|')[$ndx]
space = ' '
}
The only downside is that you do not now have the option of using special graphics characters (the Ascii switch is still there, but does nothing). Maybe someone could tell us how to embed them properly.
I am new to Powershell and Stack Overflow, so sorry if this an obvious question. I have searched and searched and have not found any similar questions or answers. I am trying to call a command on Powershell and changing the file name by one. Here is the line giving me trouble:
fconv -rmsd ${line}_O[int]($modeO+1).mol2 --s=${line}_A$modeA.mol2
This program takes a line of code in the format
fconv -rmsd FILE_NAME.mol2 --s=FILE_NAME.mol2
and gives a result. My problem is adding 1 to $modeO. $modeO is a number that is pulled from a file and converted to an int by using
$modeO = file.txt | Select -Index 0
[int]$modeO = [convert]::ToInt32($ModeO.Trim(), 10)
Now, whenever I try this command it says "could not open 5157_O6+1.mol2" when modeO is 6. I want it to use the file O7, but the +1 is not adding properly. I have tried separating it with parentheses, curly braces, and putting [int] in front of ($modeO+1). Is there a way to add to a variable like this while using it? Any help is appreciated, thank you!
I have to run a VB script which has 2 arguments. So I am running a command below.
Delete_Dummy1.vb
s C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml.csv C:\Users\c6342\Deskto
p\XML_to_CSV\Temp_Files\xml1.txt
**VB Script Sample - not working:**
**sourceloc** = WScript.Arguments.Item(0)
**destloc** = WScript.Arguments.Item(1)
Dim objFSO, dataArray, clippedArray()
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set oTextStream = objFSO.OpenTextFile("**sourceloc**")
Set newFile = objFSO.CreateTextFile("**destloc**")
It throws the error as file not found. But if I hard code the sourceloc and destloc and remove the arguments it is working fine. it is throwing error only when i am using arguments.
**Working VB Script sample:**
Set oTextStream = objFSO.OpenTextFile("C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml.csv")
Set newFile = objFSO.CreateTextFile("C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt")
This works fine. But as per my project requirement, I cant hard code these file locations. I can pass as parameters from command.
After a length discussion in the comments think it will be best to just update my answer.
The reason for the Arguments not working is you never pass them to the OpenTextFile() and CreateTextFile() methods. Instead you are passing literal strings containing the variable name instead of the actual variables.
sourceloc = WScript.Arguments.Item(0)
destloc = WScript.Arguments.Item(1)
Dim objFSO, dataArray, clippedArray()
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Pass the variables not a string literal
Set oTextStream = objFSO.OpenTextFile(sourceloc)
Set newFile = objFSO.CreateTextFile(destloc)
As it stands VBScript keeps trying to locate a file called sourceloc and destloc instead of the actual file names from the passed Arguments collection. Which is what likely causes the
Microsoft VBScript Runtime Error: File Not Found
Note: Below is based on initial question which has since been revised.
This comes down to how you are passing the arguments to the script, any spaces in the values will be treated as new arguments. At the moment this is how the arguments are passed;
0. C:\Users\enter
1. code
2. herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv
3. C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt
I'm sure this isn't what you expect. To avoid this enclose each argument in double quotes ("...").
Delete_Dummy1.vbs "C:\Users\enter code herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv" "C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt"
That way you get more what you expected
0. C:\Users\enter code herec6342\Desktop\XML_to_CSV\Temp_Files\xml.csv
1. C:\Users\c6342\Desktop\XML_to_CSV\Temp_Files\xml1.txt
I wrote a small program which generates big text files. I found using a StreamWriter is much, much faster than other methods I know. But the end of each text file is missing.
I reduced the program to a very simple snippet to spot the problem, but I'm still unable to understand how to solve it.
#$stream = [System.IO.StreamWriter] "test.txt"
# also tested with $stream = New-Object System.IO.StreamWriter("test.txt")
$i = 1
while($i -le 500) {
$stream.WriteLine("$i xxxxxx")
$i++
}
$stream.flush # flushing don't change anything
$stream.close # also tested with $stream.dispose
exit 0
Problem 1:
The end of the file is missing. Depending of line length, the last line is around 495, generaly cut in the middle of the line.
Problem 2:
When the program is finished, the text file is still locked (we can read it, but not delete/rename). We have to exit from PowerShell to gain full access to the file.
Tested on Windows 2003 and Windows 2008 with exact same result.
EDIT
dugas found the problem: I forgotten some parenthesis. Which solve the problem show with my code snippet.
But my original program have the parenthesis. So I mark this question as solved, and will open a new one when I'll found a better snippet for this specific problem.
EDIT 2
Got it. I had a hidden exception. Many thanks !
You are missing parenthesis when calling the StreamWriter's methods:
Change:
$stream.close
to
$stream.Close()
You may also want to wrap your StreamWriter in a try/finally and call Dispose on it in the finally:
try
{
$stream = [System.IO.StreamWriter] "C:\Users\168357\Documents\test2.txt"
$stream.WriteLine("xxxxxx")
}
finally
{
if ($stream -ne $NULL)
{
$stream.Dispose()
}
}
I am facing problems with Unicode named folders. When I drag the folder to the script, it doesn't show the path of the folder properly.
Simple VBScript (this is just a portion of it):
Dim Wshso : Set Wshso = WScript.CreateObject("WScript.Shell")
Dim FSO : Set FSO = CreateObject("Scripting.FileSystemObject")
If WScript.Arguments.Count = 1 Then
If FSO.FileExists(Wscript.Arguments.Item(0)) = true and FSO.FolderExists(Wscript.Arguments.Item(0)) = false Then
Alert "You dragged a file, not a folder! My god." & vbcrlf & "Script will terminate immediately", 0, "Alert: User is stupid", 48
WScript.Quit
Else
targetDir = WScript.Arguments.Item(0)
Wshso.Popup targetDir
End If
Else
targetDir = Wshso.SpecialFolders("Desktop")
Alert "Note: No folder to traverse detected, default set to:" & vbcrlf & Wshso.SpecialFolders("Desktop"), 0, "Alert", 48
End If
If it is a normal path without Unicode characters, it's fine. But in this case:
Directory: 4minute (포미닛) - Hit Your Heart
Then it will show something like 4minute (?) - Hit Your Heart
And if I do a FolderExists it can't find the dragged folder.
Is there any workaround to support Unicode named Folders?
Thanks!
I'll edit if this is not clear enough
This does seem to be a problem peculiar to the Windows Script Host's DropHandler shell extension. Whereas:
test.vbs "C:\포미닛.txt"
C:\WINDOWS\System32\WScript.exe "test.vbs" "C:\포미닛.txt"
both work when typed from the console (even if the console can't render the Hangul so it looks like ?), a drag and drop operation that should result in the same command goes through a Unicode->ANSI->Unicode translation that loses all characters that aren't in the current ANSI code page. (So 포미닛 will work on a default Korean Windows install but not Western.)
I'm not aware of a proper way to fix the problem. You could perhaps work around it by changing the DropHandler for .vbs files in the registry:
HKEY_CLASSES_ROOT\VBSFile\ShellEx\DropHandler\(Default)
from the WSH DropHandler ({60254CA5-953B-11CF-8C96-00AA00B8708C}) to {86C86720-42A0-1069-A2E8-08002B30309D}, the one used for .exe, .bat and similar, which doesn't suffer from this issue. You would also probably have to change the file association for .vbs to put quotes around the filename argument too, since the EXE DropHandler doesn't, to avoid problems with spaces in filenames.
Since this affects argument-passing for all VBS files it would be a perilous fix to deploy on any machine but your own. If you needed to do that, maybe you could try creating a new file extension with the appropriate DropTarget rather than changing VBSFile itself? Or maybe forgo drop-onto-script behaviour and provide a file Open dialog or manual drop field instead.
For anyone landing here from Google...
Bobince's tip lead me to work around this problem by wrapping my vbscript file (myscript.vbs) in a dos batch file (mybatch.bat).
The tip was:
"Seem to be a problem peculiar to the Windows Script Host's
DropHandler shell extension whereas.... the one used for .exe, .bat and
similar... doesn't suffer from this issue."
mybatch.bat contains:
:Loop
IF "%1"=="" GOTO Continue
set allfiles=%allfiles% "%1"
SHIFT
GOTO Loop
:Continue
"myscript.vbs" %allfiles%
You may also find this code from my myscript.vbs to be helpful
For Each strFullFileName In Wscript.Arguments
' do stuff
Next
Based on DG's answer, if you just want to accept one file as drop target then you can write a batch file (if you have it named as "x.bat" place VBScript with filename "x.bat.vbs" at same folder) that just contains:
#"%0.vbs" %1
the # means to not output the row on the display (I found it to show garbage text even if you use chcp 1250 as first command)
don't use double-quotes around %1, it won't work if your VBScript uses logic like the following (code I was using below was from http://jeffkinzer.blogspot.com/2012/06/vbscript-to-convert-excel-to-csv.html). Tested it and it works fine with spaces in the file and folder names:
Dim strExcelFileName
strExcelFileName = WScript.Arguments.Item(0) 'file name to parse
' get path where script is running
strScript = WScript.ScriptFullName
Dim fso
Set fso = CreateObject ("Scripting.FileSystemObject")
strScriptPath = fso.GetAbsolutePathName(strScript & "\..")
Set fso = Nothing
' If the Input file is NOT qualified with a path, default the current path
LPosition = InStrRev(strExcelFileName, "\")
if LPosition = 0 Then 'no folder path
strExcelFileName = strScriptPath & "\" & strExcelFileName
strScriptPath = strScriptPath & "\"
else 'there is a folder path, use it for the output folder path also
strScriptPath = Mid(strExcelFileName, 1, LPosition)
End If
' msgbox LPosition & " - " & strExcelFileName & " - " & strScriptPath
Modify WSH DropHandler ({60254CA5-953B-11CF-8C96-00AA00B8708C}) to {86C86720-42A0-1069-A2E8-08002B30309D} and add this function to convert short path to long:
Function Short2Long(shortFullPath)
dim fs
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(shortFullPath)
Set app = CreateObject("Shell.Application")
Short2Long = app.NameSpace(f.ParentFolder.Path).ParseName(f.Name).Path
end function