I created a small IronPython Script to list all Installed Software from a Windows PC.
import _winreg
def subkeys(key):
i = 0
while True:
try:
subkey = _winreg.EnumKey(key, i)
yield subkey
i+=1
except:
break
def traverse_registry_tree(key=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"), tabs=0):
output = []
for k in subkeys(key):
meep = _winreg.OpenKey(key,k)
if _winreg.QueryValueEx(meep,"DisplayName")[0] == None:
string = str(k)
else:
string = str(_winreg.QueryValueEx(meep,"DisplayName")[0])
output.append('\t'*tabs + string)
traverse_registry_tree(k, tabs+1)
output.sort()
return output
output_file = open("output.txt",'w')
for line in traverse_registry_tree():
tmp = line + '\n'
output_file.write(tmp)
output_file.close()
After compling it with the following Options:
/main:wmi_test.py /out:test /embed /standalone /target:winexe
I generated the output.txt from the executable and the output.txt from the script. There is however a big difference between them:
http://www.diffchecker.com/wfbh79af
Here is a screenshot from "Uninstall Software" in the Windows Configuration Center:
http://jschpp.de/software.png
Could you help me to understand why there is such a big discrepancy.
I am using IronPython 2.7 on Windows 7 Professional x64
When you say script, I assume you mean using ipy.exe wmi_test.py. The ipy.exe shipped with ironpython is a 32-bit executable (for various reasons); the executables built with pyc.py are AnyCPU, which means 64-bit for you. Windows has different registries for 32 and 64 bit programs.
An easy way to check that this is the case is to run the script with ipy64.exe instead and compare the results.
Related
I have been working on a project for a while now, and I just reached another big step! However, for some .txt files that my program creates, it will give me this message:
File was loaded in the wrong encoding: 'UTF-8'
Most of the .txt files are fine, but it gives me this error for others at the top (I can still read them). Here is my code:
from socket import *
import codecs
import subprocess
ipa = '192.168.1.' # These are the first 3 digits of the IP addresses that the program looks for.
def is_up(adr):
s = socket(AF_INET, SOCK_STREAM)
s.settimeout(0.01)
if not s.connect_ex((adr, 135)):
s.close()
return 1
else:
s.close()
def main():
for i in range(1, 256):
adr = ipa + str(i)
if is_up(adr):
with codecs.open("" + getfqdn(adr) + ".txt", "w+", 'utf-8-sig') as f:
subprocess.run('ipconfig | findstr /i "ipv4"', stdout=f, shell=True, check=True)
subprocess.run('wmic/node:'+adr+' product get name, version, vendor', stdout=f, shell=True, check=True)
main()
# Most code provided by Ashish Jain
Unfortunately I don't think I'm allowed to say exactly which files are giving me trouble, because I might be distributing information that someone can use for malicious intent.
Since your script only writes to files, there's no reason to open it in w+ mode, which enables reading. Opening the files in w mode should be enough.
Furthermore, the commands that your script runs must not be outputting in utf-8-sig-encoded text, and hence the error. In most cases outputting with default encoding by not specifying an encoding will suffice.
Lastly, you're missing a space between wmic and /node: in the second command you run.
I am trying to use Ruby to upload a PDF. My code works fine on my Linux machine, but not on the Windows 7 box I am now trying to use. I am using Ruby 2.2.0 in Windows vs 2.3.0 in Linux.
If I type the following into IRB, my results are very different on Windows vs Linux:
require 'stringio'
fname = 'C:\Sites\Programming\watir-webdriver\websign_tests\eStore.pdf'
# vs on Linux fname = '/home/me/Programming/watir-webdriver/websign_tests/eStore.pdf'
# forward slashes and backslashes give the same end result on Windows
File.readable?(fname) # => true in Windows and Linux
f_obj = File.open(fname)
f_data = StringIO.new(f_obj.read)
f_data.size # => 416 in Windows vs 186550 on Linux
#There is much less output for the following statement in Windows
#than there is in Linux
File.foreach(f_obj) {|x| print "GOT ", x }
GOT %PDF-1.4
GOT %JetForm PDF Support Version 2.3.000
GOT %EncodingObject=0
GOT %√ⁿ²■
GOT 1 0 obj
GOT <<
GOT /Type /Catalog
GOT /Pages 3 0 R
GOT /Outlines 4 0 R
GOT >>
GOT endobj
GOT
GOT 5 0 obj
GOT <<
GOT /Length 0000038826 /Filter/FlateDecode/Length1 0000057578 >>
GOT stream
GOT x┌î| |SU÷ =≈¡y/╦╦₧4]ƪI)à╢P
GOT ¶½}╩Zö]û"Ñe)P♦);╚«`í T
GOT éêRE♦§ñÇB┴♣T\G♣ù↓up♦↔╘Y∞ê♫:ÄÆ⌠⌂εK[`µ≈√}■I≤÷Σ¥{╓∩9≈╝↕ äÿ╔J┬◄}╚ê▄«╒τ∩|
GOT Å╝ïƒQôfN¿₧8ΩïrB â►±²I♂µ♣∩z╝d.!╥eB°ëS¬º╬¼ε╡⌠Sⁿü1╕⌂rΩî┼Sε¢₧qà►╗ÅÉ¥╒╙*'L~íΣ⌐┴ä∟
Xï┐╫}=> nil
I have confirmed that the PDF file size is 186,550 bytes on the Windows machine, and it opens normally with Adobe Reader.
I'm not sure why I cannot accomplish this task using Ruby and Windows 7. Am I doing something wrong, or is this a Ruby/Windows bug?
If it's a bug, is there another way to accomplish this task?
A PDF is a binary file, so you need to tell File.open to use binary mode.
This is mostly specific to Windows, as it will otherwise be treating files as text files, whereas on Linux the binary modifier is not needed (it is simply ignored).
So this is what you need:
f_obj = File.open(fname, "rb")
You can read more about the binary flag here:
https://softwareengineering.stackexchange.com/questions/238976/what-does-it-mean-that-file-io-binary-flag-is-only-relevant-on-windows
My test code is:
#!/usr/bin/env python
import win32com.client
def GetFolderSizeQuick(target_folder):
fso = win32com.client.Dispatch("Scripting.FileSystemObject")
fobj = fso.GetFolder(target_folder)
return fobj.size
print(GetFolderSizeQuick("d:/pytools"))
print(GetFolderSizeQuick("d:/cygwin"))
The result is:
D:\>python a.py
160659697
Traceback (most recent call last):
File "a.py", line 10, in <module>
print(GetFolderSizeQuick("d:/cygwin"))
File "a.py", line 7, in GetFolderSizeQuick
return fobj.size
File "D:\Applications\Python33\lib\site-packages\win32com\client\dynamic.py",
line 511, in __getattr__
ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
pywintypes.com_error: (-2147352567, '发生意外。', (0, None, None, None, 0, -2146828218), None)
The first call GetFolderSizeQuick on d:/pytools folder works. it's about 153MB. But the second call failed. The folder d:/cygwin is about 12.6GB.
I am working on windows 7 with python3.3.0 32bit version. So I think the problem happened on the 32bit or 64bit to store the result. 32bit int can not store 12.6GB size.
What is the real problem here, and how to fix it?
That's neither a directory size nor a 32/64-Bit problem.
It's even not a python2 or python3 problem.
Your Error translates to "No Access allowed!"
The simpliest way for testing would be to create a directory where only the owner is allowed to read and all others have NO rights at all. Then take this directory as input - you'll get the same error, even if the directory is empty. A good example would be the local "c:\system Volume Information".
Digging a little deeper:
The errorcodes given by python are signed, whereas for a reasonable lookup Microsoft describes and expects them as unsigned. Kudos to EB in this thread and Tim Peters in this thread, using the examples, you'll get reasonable error-Codes.
import win32com.client
import pywintypes
def get_folder_size(target_folder):
fso = win32com.client.Dispatch("Scripting.FileSystemObject")
fobj = fso.GetFolder(target_folder)
return fobj.size
if __name__ == '__main__':
try:
get_folder_size('c:/system volume information')
except pywintypes.com_error, e:
print e # debug, have to see which indices
print hex(e[0]+2**32), hex(e[2][5]+2**32)
Now search for both of the hex digits, the 2nd one should lead to a lot of "you are not allowed to..." queries and answers.
So what I am trying to accomplish is to always start. cscript.exe in native os version. SO I have access to the correct system files when my script runs and won't be redirected to the syswow64 regestry/files.
So according the msdn docs i can use the sysnative when running a 32bit application on a 64bit system to get the real system32 folder. But the script cant seam to find the the cscript.exe file. So the question is what am i doing wrong? I mostly a python guy so I might be making a stupid assumption.
This is compiled into a 32bit Service, so it could be deployed on any windows os(in theory)
Running VisualStudio 2010 if it matters
Or am I approaching the problem completely back to front?
Public Class Service1
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
'Prvents windows from redirecting us to the wow64 folder instead of system32.
' Don' run if settings file is gone
If My.Computer.FileSystem.FileExists("C:\Settings.vbs") Then
'If we are running in wow64(32bit windows files) mode switch to native 64 bit vbscript
If My.Computer.FileSystem.DirectoryExists("%systemroot%\sysnative") Then
Process.Start("%systemroot%\sysnative\cscript.exe", "C:\Main.vbs")
Else
Process.Start("%systemroot%\system32\cscript.exe", "C:\Main.vbs")
End If
End If
End Sub
Protected Overrides Sub OnStop()
' Add code here to perform any tear-down necessary to stop your service.
End Sub
End Class
Basicly to the question is How do I get cscript to run in 64bit mode rather than 32bit, so only really this line.
Process.Start("%systemroot%\system32\cscript.exe", "C:\Main.vbs")
That gets changed to C:\Windows\SysWOW64 when run a on a 64 bit system.
But stays on 32bit system it stays C:\Windows\system32.
I also tried this:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365744%28v=vs.85%29.aspx
But I cant seam to figure out how to make it work. In a vb application
Answer over there
Option Infer On
Option Strict On
Imports System.IO Module Module1 Sub Main() Dim f As String = "" If IntPtr.Size = 4 Then f = Path.Combine(Environment.ExpandEnvironmentVariables("%windir%"), "sysnative") MsgBox("Running on X86") Else f = Environment.GetFolderPath(Environment.SpecialFolder.System) MsgBox("Running on X64") End If Dim wscript As String = Path.Combine(f, "wscript.exe") Dim psi = New ProcessStartInfo psi.FileName = wscript psi.Arguments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "CheckPlatform.vbs") Dim p As New Process p.StartInfo = psi p.Start() End Sub End Module
http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/48bc23b5-798f-4cea-ae33-060a0d66506b
We use jenkins for build automation of a Visual Studio 2008 C++ Project.
In essence it's a series of calls of:
devenv solution_name /build configuration_name [/Project project_name]
which works fine in general.
To run everything out of a dos box I wrote a scala wrapper, which does the same with ProcessBuilder. It works, but I have the problem, there is not output on the console.
My guess: devenv starts a bunch of processes to compile and linke the projects in parallel. My scala programm only outputs the stdout and stderr of the devenv process, which is none. All the other output of the subprocesses is shot into nirvana.
for the sake of completness the source snippet:
def buildProject(branch: String, mode: Mode) = {
import scala.sys.process._
val lb = new ListBuffer[String]()
lb.append("devenv")
lb.append(solution)
lb.append(mode.cmd)
lb.append(config.asString)
if (!"".equals(project))
lb.append(project)
val printLogger = ProcessLogger(line => println(line), line => println(line))
val errorLevel = Process(lb.toList, new File(branch, work.sv)) ! printLogger
if (errorLevel != 0)
throw new RuntimeException("Project build failed.")
}
The List used to start the process looks like:
List(devenv, Libraries/Libraries.sln, /rebuild, Release)
Is there a way to record/output the output of the subprocesses?