Python String to BSTR - python
I am Using the iTunes COM interface on windows 7.
The method iTunes.CurrentTrack.AddArtworkFromFile(path) requires path to be of type BSTR.
I understand from some research that BSTR is a C++/Visual Basic data type that means basic string.
Is there any way of converting python ascii strings to BSTR?
code :
import urllib
from BeautifulSoup import BeautifulSoup
import re
import win32com.client
import sys
iTunes = win32com.client.gencache.EnsureDispatch("iTunes.Application")
cTrackName = iTunes.CurrentTrack.Name
cArtist = iTunes.CurrentTrack.Artist
cAlbum = iTunes.CurrentTrack.Album
print cAlbum + cArtist + cTrackName
url = 'http://www.last.fm/music/'+cArtist+'/'+cAlbum
albumPage = urllib.urlopen(url).read()
soup = BeautifulSoup(albumPage)
s = soup.prettify()
z = re.compile('.*<img width="174" src="(.*)" class="art" id="albumCover" itemprop="image" class="albumCover coverMega" />')
p = re.findall(z,s)
print p
urllib.urlretrieve(p[0],'a.png')
a = urllib.quote('file://localhost/C:/Users/ArchAngel/Desktop/a.png')
iTunes.CurrentTrack.AddArtworkFromFile('file://localhost/C:/Users/ArchAngel/Desktop/a.png')
#print binascii.a2b_uu('sadsaffas')
iTunes.CurrentTrack.AddArtworkFromFile(b'C:\Users\ArchAngel\Desktop\a.png')
Error : pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147467259), None)
Since you are using Python 2.x, I believe you simply need to use unicode rather than str and win32com will do the rest. However, I would have expected win32com to automatically convert str to unicode for you.
You should write it like this:
iTunes.CurrentTrack.AddArtworkFromFile(u'file://localhost/C:/Users/ArchAngel/Desktop/a.png')
If this does not work then I think your problem lies elsewhere.
Related
problem converting php code to python generating password digest for soap requests
<?php $password = "SECRETPASSWORD"; $nonce = random_bytes(32); # requires PHP 7 date_default_timezone_set("UTC"); $timestamp = date(DATE_ATOM); $encodedNonce = base64_encode($nonce); $passSHA = base64_encode(sha1($nonce . $timestamp . sha1($password, true), true)); ?> it generates the below result with a 28 characters password digest, which I am using in soap requests, and it works fine password_digest = '/pBYmwwc2cM87CUr8oB4Wkmyc0Q=' nonce = '���>�!��g��q�[�`�R��=J�o�' nonce_base_64_encode = 'uqbkProhsR3JZxjC93HWW8BghQFSgqo9Sv9vGgUa4hs=' timestamp = '2022-01-13T18:28:52+00:00' I need to do this same in python, but python is somehow generating longer password_digest and the soap request fails. I don't know if I am not generating the random_bytes correctly in python or some other issue. Below is python code: import secrets import hashlib import datetime clearPassword = 'MYSECRETPASSWORD' created_at_timestamp_utc = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") def getSha1String(string): stringInBytes = string.encode('ascii') hash_object = hashlib.sha1(stringInBytes) hex_dig = hash_object.hexdigest() return hex_dig def getBase64NonceString(nonce): nonce_bytes = nonce.encode('ascii') base64_bytes = base64.b64encode(nonce_bytes) base64_nonce = base64_bytes.decode('ascii') return base64_nonce def getBase64String(string): string_bytes = string.encode('ascii') base64_bytes = base64.b64encode(string_bytes) base64_string = base64_bytes.decode('ascii') return base64_string nonce = secrets.token_bytes(32) base64_nonce = getBase64Nonce(nonce) sha1_password = getSha1String(clearPassword) password_digest = getBase64String(getSha1String(str(nonce) + created_at_timestamp_utc + sha1_password))
Your python code has 3 problems: You're using binary output from sha1() in PHP, but hex output in python. Use digest(), not hexdigest(). This is why your output is longer in python. Your timestamp format is incorrect. The PHP format DATE_ATOM is "Y-m-d\TH:i:sP", where P outputs the UTC offset in the format +00:00. Unfortunately Python's strftime() doesn't seem to have an equivalent, but it's all in UTC anyway and your python code simply specifies the static string Z. So change that to +00:00, otherwise your tokens won't match. Eg: timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S+00:00') You're using SECRETPASSWORD in PHP and MYSECRETPASSWORD in python, and I am emabarrased at how long I bashed my head against that one without noticing. Succint working code: import hashlib, datetime, base64 password = 'SECRETPASSWORD' timestamp = '2022-01-13T18:28:52+00:00' nonce = base64.b64decode('uqbkProhsR3JZxjC93HWW8BghQFSgqo9Sv9vGgUa4hs=') def quickSHA(input): return hashlib.sha1(input).digest() def makeToken(password, timestamp, nonce): return base64.b64encode( quickSHA( nonce + timestamp + quickSHA(password) ) ) print makeToken(password, timestamp, nonce) Output: /pBYmwwc2cM87CUr8oB4Wkmyc0Q=
python win32 api document.getElementById Error
import win32com import win32com.client import win32gui import win32con import pythoncom def getIEServer(hwnd, ieServer): if win32gui.GetClassName(hwnd) == 'Internet Explorer_Server': ieServer.append(hwnd) if __name__ == '__main__': #pythoncom.CoInitializeEx(0) # not use this for multithreading mainHwnd = win32gui.FindWindow('windowclass', 'windowtitle') if mainHwnd: ieServers = [] win32gui.EnumChildWindows(mainHwnd, getIEServer, ieServers) if len(ieServers) > 0: ieServer = ieServers[0] msg = win32gui.RegisterWindowMessage('WM_HTML_GETOBJECT') ret, result = win32gui.SendMessageTimeout(ieServer, msg, 0, 0, win32con.SMTO_ABORTIFHUNG, 1000) ob = pythoncom.ObjectFromLresult(result, pythoncom.IID_IDispatch, 0) doc = win32com.client.dynamic.Dispatch(ob) print doc.url # doc.all['id'].click() You can get doc (document object) with the above code If you try doc.getElementById ("some-id") I get an error like the one below. TypeError: getElementById () takes 1 positional argument but 2 were given It will appear in IE11 Please Help Me T0T~ p.s The type of problem is different from the suggested answer. I think I need to fix the error in pywin32.
How do I encode properly a possibly chinese encoding in python?
I am scraping the following link: http://www.footballcornersta.com/en/league.php?select=all&league=%E8%8B%B1%E8%B6%85&year=2014&month=1&Submit=Submit and the following string contains all the available options in a menu relevant to league: ls_main = [['E','ENG PR','英超'],['E','ENG FAC','英足总杯'],['E','ENG Champ','英冠'],['E','ENG D1','英甲'],['I','ITA D1','意甲'],['I','ITA D2','意乙'],['S','SPA D1','西甲'],['S','SPA D2','西乙'],['G','GER D1','德甲'],['G','GER D2','德乙'],['F','FRA D1','法甲'],['F','FRA D2','法乙'],['S','SCO PR','苏超'],['R','RUS PR','俄超'],['T','TUR PR','土超'],['B','BRA D1','巴西甲'],['U','USA MLS','美职联'],['A','ARG D1','阿根甲'],['J','JP D1','日职业'],['J','JP D2','日职乙'],['A','AUS D1','澳A联'],['K','KOR D1','韩K联'],['C','CHN PR','中超'],['E','EURO Cup','欧洲杯'],['I','Italy Supe','意超杯'],['K','KOR K3','K3联'],['C','CHN D1','中甲'],['D','DEN D2-E','丹乙东'],['D','DEN D2-W','丹乙西'],['D','DEN D1','丹甲'],['D','DEN PR','丹超'],['U','UKR U21','乌克兰U21'],['U','UD2','乌克甲'],['U','UKR D1','乌克超'],['U','Uzber D1','乌兹超'],['U','URU D1','乌拉甲'],['U','UZB D2','乌茲甲'],['I','ISR D2','以色列乙'],['I','ISR D1','以色列甲'],['I','ISR PR','以色列超'],['I','Iraq L','伊拉联'],['I','Ira D1','伊朗甲'],['I','IRA P','伊朗联'],['R','RUS D2C','俄乙中'],['R','RUS D2U','俄乙乌'],['R','RUS D2S','俄乙南'],['R','RUS D2W','俄乙西'],['R','RUS RL','俄后赛'],['R','RUS D1','俄甲'],['R','RUS PR','俄超'],['B','BUL D1','保甲'],['C','CRO D1','克甲'],['I','ICE PR','冰岛超'],['G','GHA PL','加纳超'],['H','Hun U19','匈U19'],['H','HUN D2E','匈乙东'],['H','HUN D2W','匈乙西'],['H','HUN D1','匈甲'],['N','NIR IFAC','北爱冠'],['N','NIRE PR','北爱超'],['S','SAfrica D1','南非甲'],['S','SAfrica NSLP','南非超'],['L','LUX D1','卢森甲'],['I','IDN PR','印尼超'],['I','IND D1','印度甲'],['G','GUAT D1','危地甲'],['E','ECU D1','厄甲'],['F','Friendly','友谊赛'],['K','KAZ D1','哈萨超'],['C','COL D2','哥伦乙'],['C','COL C','哥伦杯'],['C','COL D1','哥伦甲'],['C','COS D1','哥斯甲'],['T','TUR U23','土A2青'],['T','TUR D3L1','土丙1'],['T','TUR D3L2','土丙2'],['T','TUR D3L3','土丙3'],['T','TUR2BK','土乙白'],['T','TUR2BB','土乙红'],['T','TUR D1','土甲'],['E','EGY PR','埃及超'],['S','Serbia D2','塞尔乙'],['S','Serbia 1','塞尔联'],['C','CYP D2','塞浦乙'],['C','CYP D1','塞浦甲'],['M','MEX U20','墨西U20'],['M','Mex D2','墨西乙'],['M','MEX D1','墨西联'],['A','AUT D3E','奥丙东'],['A','AUT D3C','奥丙中'],['A','AUT D3W','奥丙西'],['A','AUT D2','奥乙'],['A','AUT D1','奥甲'],['V','VEN D1','委超'],['W','WAL D2','威甲'],['W','WAL D2CA','威联盟'],['W','WAL D1','威超'],['A','Ang D1','安哥甲'],['N','NIG P','尼日超'],['P','PAR D1','巴拉甲'],['B','BRA D2','巴西乙'],['B','BRA CP','巴锦赛'],['G','GRE D3N','希丙北'],['G','GRE D3S','希丙南'],['G','GRE D2','希乙'],['G','GRE D1','希甲'],['G','GER U17','德U17'],['G','GER U19','德U19'],['G','GER D3','德丙'],['G','GER RN','德北联'],['G','GER RS','德南联'],['G','GER RW','德西联'],['I','ITA D3A','意丙A'],['I','ITA D3B','意丙B'],['I','ITA D3C1','意丙C1'],['I','ITA D3C2','意丙C2'],['I','ITA CP U20','意青U20'],['E','EST D3','愛沙丙'],['N','NOR D2-A','挪乙A'],['N','NOR D2-B','挪乙B'],['N','NOR D2-C','挪乙C'],['N','NOR D2-D','挪乙D'],['N','NORC','挪威杯'],['N','NOR D1','挪甲'],['N','NOR PR','挪超'],['C','CZE D3','捷丙'],['C','CZE MSFL','捷丙M'],['C','CZE D2','捷乙'],['C','CZE U19','捷克U19'],['C','CZE D1','捷克甲'],['M','Mol D2','摩尔乙'],['M','MOL D1','摩尔甲'],['M','MOR D2','摩洛哥乙'],['M','MOR D1','摩洛超'],['S','Slovakia D3E','斯丙東'],['S','Slovakia D3W','斯丙西'],['S','Slovakia D2','斯伐乙'],['S','Slovakia D1','斯伐甲'],['S','Slovenia D1','斯洛甲'],['S','SIN D1','新加联'],['J','JL3','日丙联'],['C','CHI D2','智乙'],['C','CHI D1','智甲'],['G','Geo','格鲁甲'],['G','GEO PR','格鲁超'],['U','UEFA CL','欧冠杯'],['U','UEFA SC','欧霸杯'],['B','BEL D3A','比丙A'],['B','BEL D3B','比丙B'],['B','BEL D2','比乙'],['B','BEL W1','比女甲'],['B','BEL C','比杯'],['B','BEL D1','比甲'],['S','SAU D2','沙地甲'],['S','SAU D1','沙地联'],['F','FRA D4A','法丁A'],['F','FRA D4B','法丁B'],['F','FRA D4C','法丁C'],['F','FRA D4D','法丁D'],['F','FRA D3','法丙'],['F','FRA U19','法国U19'],['F','FRA C','法国杯'],['P','POL D2E','波乙東'],['P','POL D2W','波乙西'],['P','POL D2','波兰乙'],['P','POL D1','波兰甲'],['B','BOS D1','波斯甲'],['P','POL YL','波青联'],['T','THA D1','泰甲'],['T','THA PL','泰超'],['H','HON D1','洪都甲'],['A','Aus BP','澳布超'],['E','EST D1','爱沙甲'],['I','IRE D1','爱甲'],['I','IRE PR','爱超'],['B','BOL D1','玻利甲'],['F','Friendly','球会赛'],['S','SWI D1','瑞士甲'],['S','SWI PR','瑞士超'],['S','SWE D2','瑞甲'],['S','SWE D1','瑞超'],['B','BLR D2','白俄甲'],['B','BLR D1','白俄超'],['P','Peru D1','秘鲁甲'],['T','TUN D2','突尼乙'],['T','Tun D1','突尼甲'],['R','ROM D2G1','罗乙1'],['R','ROM D2G2','罗乙2'],['R','ROM D1','罗甲'],['L','LIBERT C','自由杯'],['F','FIN D2','芬甲'],['F','FIN D1','芬超'],['S','SCO D3','苏丙'],['S','SUD PL','苏丹超'],['S','SCO D2','苏乙'],['S','SCO D1','苏甲'],['S','SCO HL','苏高联'],['E','ENG D2','英乙'],['E','ENG RyPR','英依超'],['E','ENG UP','英北超'],['E','ENG SP','英南超'],['E','ENG Trophy','英挑杯'],['E','ENG Con','英非'],['E','ENG CN','英非北'],['H','HOL D2','荷乙'],['H','HOL Yl','荷青甲'],['S','SV D1','萨尔超'],['P','POR U19','葡U19'],['P','POR D1','葡甲'],['P','POR PR','葡超'],['S','SPA D3B1','西丙1'],['S','SPA D3B2','西丙2'],['S','SPA D3B3','西丙3'],['S','SPA D3B4','西丙4'],['S','SPA Futsal','西內足'],['S','SPA W1','西女超'],['B','BRA CC','里州赛'],['A','Arg D2M1','阿乙M1'],['A','Arg D2M2','阿乙M2'],['A','Arg D2M3','阿乙M3'],['A','ALG D2','阿及乙'],['A','ALG D1','阿及甲'],['A','AZE D1','阿塞甲'],['A','ALB D1','阿巴超'],['A','ARG D2','阿根乙'],['U','UAE D2','阿联乙'],['K','KOR NL','韩联盟'],['F','FYRM D2','马其乙'],['M','MacedoniaFyr','马其甲'],['M','MAS D1','马来超'],['M','MON D2','黑山乙'],['M','MON D1','黑山甲'],['F','FCWC','世冠杯'],['W','World Cup','世界杯'],['F','FIFAWYC','世青杯'],['C','CWPL','中女超'],['C','CFC','中足协杯'],['D','DEN C','丹麦杯'],['A','Asia CL','亚冠杯'],['A','AFC','亚洲杯'],['R','Rus Cup','俄罗斯杯'],['H','HUN C','匈杯'],['N','NIR C','北爱杯'],['T','TUR C','土杯'],['T','Tenno Hai','天皇杯'],['W','WWC','女世杯'],['I','ITA Cup','意杯'],['G','GER C','德国杯'],['J','JPN LC','日联杯'],['S','SCO FAC','苏足总杯'],['E','ENG JPT','英锦赛'],['E','ENG FAC','足总杯'],['C','CAF NC','非洲杯'],['K','K-LC','韩联杯'],['H','HK D1','香港甲']]; The link of the page I am scraping contains the third character, but when I copy it becomes the link above. I am not sure about the encoding. import re html = 'source of page' matches = re.findall('ls_main = \[\[.*?;', html)[0] matches = matches.decode('unknown encoding').encode('utf-8') How can I put the original character in the string of the link ? I use Python 2.7.
%XX encoding can be done using urllib.qutoe: >>> import urllib >>> urllib.quote('英冠') '%E8%8B%B1%E5%86%A0' >>> urllib.quote(u'英冠'.encode('utf-8')) # with explicit utf-8 encoding. '%E8%8B%B1%E5%86%A0' To get back the original string, use urllib.unquote: >>> urllib.unquote('%E8%8B%B1%E5%86%A0') '\xe8\x8b\xb1\xe5\x86\xa0' >>> print(urllib.unquote('%E8%8B%B1%E5%86%A0')) 英冠 In Python 3.x, use urllib.parse.quote, urllib.parse.unquote: >>> import urllib.parse >>> urllib.parse.quote('英冠', encoding='utf-8') '%E8%8B%B1%E5%86%A0' >>> urllib.parse.unquote('%E8%8B%B1%E5%86%A0', encoding='utf-8') '英冠'
decoding base64 guid in python
I am trying to convert a base64 string back to a GUID style hex number in python and having issues. Base64 encoded string is: bNVDIrkNbEySjZ90ypCLew== And I need to get it back to: 2243d56c-0db9-4c6c-928d-9f74ca908b7b I can do it with the following PHP code but can't work out how to to it in Python function Base64ToGUID($guid_b64) { $guid_bin = base64_decode($guid_b64); return join('-', array( bin2hex(strrev(substr($guid_bin, 0, 4))), bin2hex(strrev(substr($guid_bin, 4, 2))), bin2hex(strrev(substr($guid_bin, 6, 2))), bin2hex(substr($guid_bin, 8, 2)), bin2hex(substr($guid_bin, 10, 6)) )); } Here is the GUIDtoBase64 version: function GUIDToBase64($guid) { $guid_b64 = ''; $guid_parts = explode('-', $guid); foreach ($guid_parts as $k => $part) { if ($k < 3) $part = join('', array_reverse(str_split($part, 2))); $guid_b64 .= pack('H*', $part); } return base64_encode($guid_b64); } Here are some of the results using some of the obvious and not so obvious options: import base64 import binascii >>> base64.b64decode("bNVDIrkNbEySjZ90ypCLew==") 'l\xd5C"\xb9\rlL\x92\x8d\x9ft\xca\x90\x8b{' >>> binascii.hexlify(base64.b64decode("bNVDIrkNbEySjZ90ypCLew==")) '6cd54322b90d6c4c928d9f74ca908b7b'
Python port of the existing function (bitstring required) import bitstring, base64 def base64ToGUID(b64str): s = bitstring.BitArray(bytes=base64.b64decode(b64str)).hex def rev2(s_): def chunks(n): for i in xrange(0, len(s_), n): yield s_[i:i+n] return "".join(list(chunks(2))[::-1]) return "-".join([rev2(s[:8]),rev2(s[8:][:4]),rev2(s[12:][:4]),s[16:][:4],s[20:]]) assert base64ToGUID("bNVDIrkNbEySjZ90ypCLew==") == "2243d56c-0db9-4c6c-928d-9f74ca908b7b"
First off, the b64 string and the resultant GUID doesn't match if we decode properly. >>> import uuid >>> import base64 >>> u = uuid.UUID("2243d56c-0db9-4c6c-928d-9f74ca908b7b") >>> u UUID('2243d56c-0db9-4c6c-928d-9f74ca908b7b') >>> u.bytes '"C\xd5l\r\xb9Ll\x92\x8d\x9ft\xca\x90\x8b{' >>> base64.b64encode(u.bytes) 'IkPVbA25TGySjZ90ypCLew==' >>> b = base64.b64decode('bNVDIrkNbEySjZ90ypCLew==') >>> u2 = uuid.UUID(bytes=b) >>> print u2 6cd54322-b90d-6c4c-928d-9f74ca908b7b The base64 encoded version of the resultant GUID you posted is wrong. I'm not sure I understand the way you're encoding the GUID in the first place. Python has in its arsenal all the tools required for you to be able to answer this problem. However, here's the rough scratching I did in a python terminal: import uuid import base64 base64_guid = "bNVDIrkNbEySjZ90ypCLew==" bin_guid = base64.b64decode(base64_guid) guid = uuid.UUID(bytes=bin_guid) print guid This code should give you enough of a hint to build your own functions. Don't forget, the python shell gives you a powerful tool to test and play with code and ideas. I would investigate using something like IPython notebooks.
I needed to do this to decode a BASE64 UUID that had been dumped from Mongodb. Originally the field had been created by Mongoose. The code I used, based on the code by #tpatja is here: def base64ToGUID(b64str): try: bytes=base64.urlsafe_b64decode(b64str) except Exception as e: print("Can't decode base64 ", e) s = bitstring.BitArray(bytes).hex return "-".join([s[:8],s[8:][:4],s[12:][:4],s[16:][:4],s[20:]])
Based on good answers above, I wrote a version that does not require the bitstring package and includes validations and support for more input options. import base64 import regex import uuid from typing import Optional def to_uuid(obj) -> Optional[uuid.UUID]: if obj is None: return None elif isinstance(obj, uuid.UUID): return obj elif isinstance(obj, str): if regex.match(r'[0-9a-fA-F]{8}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{4}[-]{0,1}[0-9a-fA-F]{12}', obj): return uuid.UUID(hex=obj) elif regex.match(r'[0-9a-zA-Z\+\/]{22}[\=]{2}', obj): b64_str = base64.b64decode(obj).hex() uid_str = '-'.join([b64_str[:8], b64_str[8:][:4], b64_str[12:][:4], b64_str[16:][:4], b64_str[20:]]) return uuid.UUID(hex=uid_str) raise ValueError(f'{obj} is not a valid uuid/guid') else: raise ValueError(f'{obj} is not a valid uuid/guid')
python win32print not printing
I need to print some information directly (without user confirmation) and I'm using Python and the win32print module. I've already read the whole Tim Golden win32print page (even read the win32print doc, which is small) and I'm using the same example he wrote there himself, but I just print nothing. If I go to the interactive shell and make one step at a time, I get the document on the printer queue (after the StartDocPrinter), then I get the document size (after the StartPagePrinter, WritePrinter, EndPagePrinter block) and then the document disappear from the queue (after the EndDocPrinter) without printing. I'm aware of the ShellExecute method Tim Golden showed. It works here, but it needs to create a temp file and it prints this filename, two things I don't want. Any ideas? Thanks in advance. This is the code I'm testing (copy and paste of Tim Golden's): import os, sys import win32print import time printer_name = win32print.GetDefaultPrinter() if sys.version_info >= (3,): raw_data = bytes ("This is a test", "utf-8") else: raw_data = "This is a test" hPrinter = win32print.OpenPrinter (printer_name) try: hJob = win32print.StartDocPrinter (hPrinter, 1, ("test of raw data", None, "RAW")) try: win32print.StartPagePrinter (hPrinter) win32print.WritePrinter (hPrinter, raw_data) win32print.EndPagePrinter (hPrinter) finally: win32print.EndDocPrinter (hPrinter) finally: win32print.ClosePrinter (hPrinter) [EDIT] I installed a pdf printer in my computer to test with another printer (CutePDF Writer) and I could generate the test of raw data.pdf file, but when I look inside there is nothing. Meaning: all commands except WritePrinter appears to be doing what they were supposed to do. But again, as I said in the comments, WritePrinter return the correct amount of bytes that were supposed to be written to the printer. I have no other idea how to solve this, but just comproved there is nothing wrong with my printer.
I'm still looking for the best way to do this, but I found an answer that satisfy myself for the problem that I have. In Tim Golden's site (linked in question) you can find this example: import win32ui import win32print import win32con INCH = 1440 hDC = win32ui.CreateDC () hDC.CreatePrinterDC (win32print.GetDefaultPrinter ()) hDC.StartDoc ("Test doc") hDC.StartPage () hDC.SetMapMode (win32con.MM_TWIPS) hDC.DrawText ("TEST", (0, INCH * -1, INCH * 8, INCH * -2), win32con.DT_CENTER) hDC.EndPage () hDC.EndDoc () I adapted it a little bit after reading a lot of the documentation. I'll be using win32ui library and TextOut (device context method object). import win32ui # X from the left margin, Y from top margin # both in pixels X=50; Y=50 multi_line_string = input_string.split() hDC = win32ui.CreateDC () hDC.CreatePrinterDC (your_printer_name) hDC.StartDoc (the_name_will_appear_on_printer_spool) hDC.StartPage () for line in multi_line_string: hDC.TextOut(X,Y,line) Y += 100 hDC.EndPage () hDC.EndDoc () I searched in meta stackoverflow before answering my own question and here I found it is an encouraged behavior, therefore I'm doing it. I'll wait a little more to see if I get any other answer.
# U must install pywin32 and import modules: import win32print, win32ui, win32con # X from the left margin, Y from top margin # both in pixels X=50; Y=50 # Separate lines from Your string # for example:input_string and create # new string for example: multi_line_string multi_line_string = input_string.splitlines() hDC = win32ui.CreateDC () # Set default printer from Windows: hDC.CreatePrinterDC (win32print.GetDefaultPrinter ()) hDC.StartDoc (the_name_will_appear_on_printer_spool) hDC.StartPage () for line in multi_line_string: hDC.TextOut(X,Y,line) Y += 100 hDC.EndPage () hDC.EndDoc () #I like Python
The problem is the driver Version. If the Version is 4 you need to give XPS_PASS instead of RAW, here is a sample. drivers = win32print.EnumPrinterDrivers(None, None, 2) hPrinter = win32print.OpenPrinter(printer_name) printer_info = win32print.GetPrinter(hPrinter, 2) for driver in drivers: if driver["Name"] == printer_info["pDriverName"]: printer_driver = driver raw_type = "XPS_PASS" if printer_driver["Version"] == 4 else "RAW" try: hJob = win32print.StartDocPrinter(hPrinter, 1, ("test of raw data", None, raw_type)) try: win32print.StartPagePrinter(hPrinter) win32print.WritePrinter(hPrinter, raw_data) win32print.EndPagePrinter(hPrinter) finally: win32print.EndDocPrinter(hPrinter) finally: win32print.ClosePrinter(hPrinter)