bdg2814 Posted November 14, 2013 Posted November 14, 2013 I am having problems running the DOS copy command from within a script. Ultimately, I want to combine the cotents of files A and B into file C. This snippet only shows one file being copied which could be done with the filecopy function. Since I have to combine two different files into one I thought I could use the DOS copy command with the following syntax copy "A"+"B" "C" I could not get that to work with the run command, runwait, shellexecute etc. so I simplifed the command to get the to work with only one file figuring that I could add the second file once the syntax was correct. Code as follows $cmd = @ComSpec & ' /c copy ' & '"' & $Tmp_EmpFileFullFN & '" "' & $EmpFileFullFN & '"' $RStat = Run($cmd, "", @SW_MAXIMIZE) ConsoleWrite($cmd & " (" & $RStat & ") (" & @error & ")") Output from the consolewrite command C:WINDOWScmd.exe /c copy "C:tempemployeeemployee.csv.tmp" "C:tempemployeeemployee.csv" both the $RStat and @error return a zero value. All of the commands from above appear to return a non-zero value if successful. When I look at the temp folder the employee.csv is not created. Can anyone point me in the right direction?
BrewManNH Posted November 15, 2013 Posted November 15, 2013 Run returns the PID of the program being run, if there's no error the @error value will be zero, if there is an error then it will be anything but zero. So, if the @error is not returning zero, you have a problem. Have you tried the FileCopy function in AutoIt instead? If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator
bdg2814 Posted November 15, 2013 Author Posted November 15, 2013 I need to be able to concatenate two files A+B into one file "C". The Filecopy command seems to only work with one file. Short of reading both file in a loop and writting them out to the same file in append mode seems to be the only option. The variable $RStat and @error in my previous example both return a 0. when you look at the folder where the final file is suppose to be created there is nothing there.
MHz Posted November 15, 2013 Posted November 15, 2013 This what I tested with and gives expected results. If Not FileExists('1.txt') Then FileWrite('1.txt', '1' & @CRLF) If Not FileExists('2.txt') Then FileWrite('2.txt', '2' & @CRLF) $pid = Run('"' & @ComSpec & '" /c copy 1.txt + 2.txt 3.txt', '', @SW_HIDE, 8) $merged = _StdOutRead($pid) ConsoleWrite($merged & @CRLF) ; C:\temp\employee exists $Tmp_EmpFileFullFN = 'C:\temp\employee\employee.csv.tmp' $EmpFileFullFN = 'C:\temp\employee\employee.csv' If Not FileExists($Tmp_EmpFileFullFN) Then FileWrite($Tmp_EmpFileFullFN, '1' & @CRLF) $cmd = @ComSpec & ' /c copy ' & '"' & $Tmp_EmpFileFullFN & '" "' & $EmpFileFullFN & '"' $RStat = Run($cmd, "", @SW_MAXIMIZE, 8) $merged = _StdOutRead($RStat) ConsoleWrite($merged & @CRLF) ConsoleWrite($cmd & " (" & $RStat & ") (" & @error & ")" & @CRLF) $pid = Run('"' & @ComSpec & '" /c where cmd.exe', '', @SW_HIDE, 8) $merged = _StdOutRead($pid) MsgBox(0, 'Where cmd.exe', @ComSpec & @CRLF & $merged & @CRLF & 'C:\WINDOWS\cmd.exe?') Func _StdOutRead($pid) Local $output Do Sleep(10) $output &= StdOutRead($pid) Until @error Return $output EndFunc Output: 1.txt 2.txt 1 file(s) copied. 1 file(s) copied. C:\Windows\system32\cmd.exe /c copy "C:\temp\employee\employee.csv.tmp" "C:\temp\employee\employee.csv" (4888) (0) Notice cmd.exe is in the system directory. Msgbox: --------------------------- Where cmd.exe --------------------------- C:\Windows\system32\cmd.exe C:\Windows\System32\cmd.exe C:\WINDOWS\cmd.exe? --------------------------- OK --------------------------- 3.txt 1 2 employee.csv 1 All passed the test. So I am unsure of what is happening to your test.
bdg2814 Posted November 15, 2013 Author Posted November 15, 2013 I have modfied the script you gave me just a bit and still no luck $Tmp_EmpFileFullFN = 'C:tempemployeeemployee.csv.tmp' $EmpFileFullFN = 'C:tempemployeeemployee.csv' $EmpFileCustFullFN = 'C:tempemployeeCust.csv' If Not FileExists($Tmp_EmpFileFullFN) Then FileWrite($Tmp_EmpFileFullFN, '1' & @CRLF) Local $ComSpec = @ComSpec & "system32" $pid = Run('"' & $ComSpec & '" dir /c ', '', @SW_MAXIMIZE, 8) $merged = _StdOutRead($pid) MsgBox(0, 'Dir ', $merged & @CRLF) $cmd = $ComSpec & ' /c copy ' & '"' & $Tmp_EmpFileFullFN & '"+"' & $EmpFileCustFullFN & '" "' & $EmpFileFullFN & '"' $RStat = Run($cmd, "", @SW_MAXIMIZE, 8) $merged = _StdOutRead($RStat) ConsoleWrite($merged & @CRLF) ConsoleWrite($cmd & " (" & $RStat & ") (" & @error & ")" & @CRLF) $pid = Run('"' & $ComSpec & '" dir /c ', '', @SW_MAXIMIZE, 8) $merged = _StdOutRead($pid) MsgBox(0, 'Dir', $merged & @CRLF) Func _StdOutRead($pid) Local $output Do Sleep(10) $output &= StdOutRead($pid) Until @error Return $output EndFunc I have attached a screen print of the debugger output and the dos window with the contents of each file displayed after the script has run. The variables $RStat and @error are both zero and the veriable $merged show no value. Not sure if they are null or blank but nothing displays in the msgbox.
bdg2814 Posted November 15, 2013 Author Posted November 15, 2013 Modified it one last time with the output window below $Tmp_EmpFileFullFN = 'C:tempemployeeemployee.csv.tmp' $EmpFileFullFN = 'C:tempemployeeemployee.csv' $EmpFileCustFullFN = 'C:tempemployeeCust.csv' If Not FileExists($Tmp_EmpFileFullFN) Then FileWrite($Tmp_EmpFileFullFN, '1' & @CRLF) Local $ComSpec = @ComSpec & "system32" $pid = Run('"' & $ComSpec & '" dir /c ', '', @SW_MAXIMIZE, 8) $merged = _StdOutRead($pid) ;MsgBox(0, 'Dir ', $merged & @CRLF) ConsoleWrite('Line ' & @ScriptLineNumber & ' Length of $merged = [' & StringLen($merged) & ']' & @CRLF) $cmd = $ComSpec & ' /c copy ' & '"' & $Tmp_EmpFileFullFN & '"+"' & $EmpFileCustFullFN & '" "' & $EmpFileFullFN & '"' $RStat = Run($cmd, "", @SW_MAXIMIZE, 8) $merged = _StdOutRead($RStat) ;ConsoleWrite($merged & @CRLF) ConsoleWrite('Line ' & @ScriptLineNumber & ' Length of $merged = [' & StringLen($merged) & ']' & @CRLF) ConsoleWrite($cmd & " (" & $RStat & ") (" & @error & ")" & @CRLF) $pid = Run('"' & $ComSpec & '" dir /c ', '', @SW_MAXIMIZE, 8) $merged = _StdOutRead($pid) ;MsgBox(0, 'Dir', $merged & @CRLF) ConsoleWrite('Line ' & @ScriptLineNumber & ' Length of $merged = [' & StringLen($merged) & ']' & @CRLF) Func _StdOutRead($pid) Local $output Do Sleep(10) $output &= StdOutRead($pid) Until @error Return $output EndFunc Output window---------------------------------------------------------- Line 61 Length of $merged = [0] Line 87 Length of $merged = [0] C:\Windows\System32\ /c copy "C:tempemployeeemployee.csv.tmp"+"C:tempemployeeCust.csv" "C:tempemployeeemployee.csv" (0) (0) Line 113 Length of $merged = [0]
MHz Posted November 16, 2013 Posted November 16, 2013 Thanks for the picture. So you are using Windows XP. $ComSpec is C:\Windows\System32\ and the command prompt window title is C:\Windows\System32\cmd.exe. The title is correct though $ComSpec is not correct. C:\Windows\System32\ will not work well with parameters so I would expect failure in your last attempts. If I test $ComSpec as your script sets it, I get C:\Windows\System32\cmd.exesystem32 which I would expect from system32 being appended to @ComSpec. It looks as if the ComSpec environmental variable path has been changed. Still does not explain how the 1st post has cmd.exe appended, hmm. Try this in your command prompt. echo %ComSpec% You should get a return the same as your prompt window which would be C:\Windows\System32\cmd.exe. If it does not then try the script below. expandcollapse popup$regkeyEnvironment = 'HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' $regdatComSpec = '%SystemRoot%\system32\cmd.exe' ; check if parameter passed to the script If $CMDLINE[0] Then ; only /update parameter If $CMDLINE[1] = '/update' Then _Update() EndIf Exit EndIf ; get ComSpec path from registry. Expect %SystemRoot%\system32\cmd.exe $ComSpec = RegRead($regkeyEnvironment, 'ComSpec') MsgBox(0, 'ComSpec path from registry', $ComSpec) If $ComSpec And $ComSpec <> $regdatComSpec Then ; this checks if the expected path to cmd.exe exists If Not FileExists(EnvGet('SystemRoot') & '\system32\cmd.exe') Then MsgBox(0x40030, @ScriptName, 'Not found ' & EnvGet('SystemRoot') & '\system32\cmd.exe') Exit 1 EndIf ; prompt to update the registry. Will start a 2nd instance of script if yes If MsgBox(0x40024, @ScriptName, 'Do you want to update the ComSpec path in the registry?') = 6 Then ; yes If IsAdmin() Then _Update() Else ; if not admin start another instance with runas verb ShellExecuteWait('"' & @AutoItExe & '"', '/AutoIt3ExecuteScript "' & @ScriptFullPath & '" /update', '', 'runas') EndIf EndIf EndIf MsgBox(0, @ScriptName, 'Task is finished') Exit Func _Update() If RegWrite($regkeyEnvironment, 'ComSpec', 'REG_EXPAND_SZ', $regdatComSpec) Then ; update the environment as to the change. May need to restart apps that depend on ComSpec path or at worst, restart OS EnvUpdate() MsgBox(0x40000, @ScriptName, 'Registry updated') Else MsgBox(0x40000, @ScriptName, 'Registry not updated') EndIf EndFunc Tested on Windows 7. The script will check the registry value of ComSpec and will show a MsgBox with hopefully %SystemRoot%system32cmd.exe in it. If not, then you may see another MsgBox to update the registry value of ComSpec. If acceptable, then click yes to write %SystemRoot%system32cmd.exe as the value of ComSpec. A second instance of the script may do the change if you are not admin. Perhaps you should check the rest of the environmental variables by just typing set in the command prompt and check the return. set If fixed, then @ComSpec may work better in your script.
bdg2814 Posted November 18, 2013 Author Posted November 18, 2013 I made the appropriate changes to the WinReg and things seem to be working better. I checked several other workstations and they all had the comspec set correctly. Not sure why mine was different. I rebooted the workstation and then checked again. The WinReg again had the correct values so it does not appear to be the work of some program or group policy setting it to the wrong value. For not it works. Thanks.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now