1

Final update:

Once the password correct other passwords can open the excel so if divide the Process into 4, when the first password mathed other 3 Process will put the nearly password to open the excel(at this time the excel has already opend) so there will show 4 correct password.

def mainstep(file,passwords,threadname):
    time_begin = time.time()
    pythoncom.CoInitialize()
    excel = Dispatch("Excel.Application")
    excel.Visible = False
    for password in passwords:
        try:
            excel.Workbooks.Open(file, False, True, None, Password=password)
        except pywintypes.com_error:
            excel.Application.Quit()
            #print('Threadname '+str(threadname)+' Error '+str(password))
            pass
        else:
            print('Success '+str(password))
            excel.Application.Quit()
            time_end=time.time()
            print('time:{} seconds '.format(time_end-time_begin))
            break

Update the codes based on the answer:

def mainstep(file,passwords):
    pythoncom.CoInitialize()
    excel = Dispatch("Excel.Application")
    excel.Visible = False
    for password in passwords:
        try:
            excel.Workbooks.Open(file, False, True, None, Password=password)
        except pywintypes.com_error:
            pass
        else:
            print('Success '+password)
            break
if __name__ == '__main__':
    NUMBER_OF_PROCESSES = 4
    groups = [passw[i::NUMBER_OF_PROCESSES] for i in range(NUMBER_OF_PROCESSES)]
    for group in groups:
        p = Process(target=mainstep, args=(path,group))
        p.start()

i set the excel passoword is 'wulong' then when i run the codes it output the result are:

Success wwwwww
Success wwwwwu
Success wwwwwl
Success wwwwwo

It's really really confused.

============================================================

I am trying to find out the password of an excel workbook.

First I use itertools to create my password dictionary

import itertools,os,sys
from win32com.client import Dispatch
import pywintypes
import threading
import pythoncom
# setting the password words
path='C:/Users/M_Seas/Desktop/file.xlsx'
words='lowung'
passw=[]
pw=itertools.product(words,repeat=6)
# write all combination into dic and list
dic=open("password.txt","a")
for word in pw:
    dic.write(''.join(word)+'\n')
dic.close()
with open("password.txt","r") as f:
    for word in f.readlines():
        passw.append(word.strip('\n'))

Then the next step is to use these combination to open the excel workbook:

def mainstep(path):
    pythoncom.CoInitialize()
    excel = Dispatch("Excel.Application")
    excel.Visible = False
    for i in passw:
        try:
            excel.Workbooks.Open(path, False, True, None, Password=i)
        except pywintypes.com_error:
            print('Error '+i)
        else:
            print('Success '+i)
            break

But this way is too slow to find out the correct key, so I use threading to speed it up.

I want to divide it into 5 threads:

for i in range(5):
    t = threading.Thread(target=mainstep, args=(path,))
    t.start()
>>Error llllll
Error llllll
Error llllll
Error llllll
Error llllll
Error lllllo
Error lllllo
Error lllllo
Error lllllo
Error lllllo

Finally I found, that the 5 threads are all checking the same passwords. In which way can I really split the passwords into 5 parts and then process them with multiple threads to make it speed up??

M_Sea
  • 389
  • 4
  • 13

1 Answers1

2

First of all, threading does not help you here. The key is multiprocessing. As stated in this detailed comparison, threading is used to make responsive applications, while not able to use multiple CPU cores to run in parrallel.

multiprocessing is used to parrallelize your code using multiple CPU cores, to make your program run faster.

To use multiprocessing you have to split up your combinations by grouping all password combinations in NUMBER_OF_PROCESSES parts and start one process for each group.

from multiprocessing import Process

passw = [ ... ] # your list of passwords, obtained by reading your file
NUMBER_OF_PROCESSES = 4 # the number of processes you want to use

# split your passw list in NUMBER_OF_CORES parts
groups = [passw[i::NUMBER_OF_PROCESSES] for i in range(NUMBER_OF_PROCESSES)]

# spawn processes
for group in groups:
    p = Process(target=mainstep, args=(path,group))
    p.start()

You have to change your mainstep function to take an additional argument passwords to be processed, e.g.

def mainstep(path, passwords):
    # ... something ...
    for password in passwords:
        # open excel and try password
Erich
  • 1,838
  • 16
  • 20
  • In ```groups = [ls[i::NUMBER_OF_PROCESSES] for i in range(NUMBER_OF_PROCESSES)]``` what does the ```ls``` means?? – M_Sea Apr 18 '20 at 12:40
  • Ah my bad. It refers to `pasw`. – Erich Apr 18 '20 at 12:41
  • I modify the codes and run it but it get the multi-correct keys as results, what cause it??? I update the codes at the beginning of the question – M_Sea Apr 18 '20 at 13:01
  • Can you try reading something from the excel file in `mainstep`? Is the password really set? Is Excel already open? – Erich Apr 18 '20 at 13:08
  • Finally it run successfully but the process time is really the same between using ```Process``` or just run ```mainstep```, i am not sure why cause it – M_Sea Apr 18 '20 at 15:41
  • Maybe the multiple excel processes block each other, e.g. you can't have multiple excel instances up at the same time. Also, how many cpu cores do you have? – Erich Apr 18 '20 at 15:47
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/211985/discussion-between-m-sea-and-erich). – M_Sea Apr 19 '20 at 01:20