简体   繁体   中英

Task scheduler won't run python script (pywin32) to open Excel. How to get more info from Pywin32

I have a Python script running on Windows Server 2008. It opens a spreadsheet and adds a filter row to the spreadsheet, closes it and then zips it up. The main spreadsheet is created using xlwt. I only use Pywin32 because the users want to have a filter row added.

When executing this manually (ie directly via Windows Explorer or command line) it works. However, when firing the script manually through Task Schduler or letting it trigger at the required time, it does not work.

The 'run as' user is an administrator. I have checked to make sure it runs with the highest privileges.

I captured the error message by piping the output to a log file. The traceback shows:

File "C:\www\..\main\management\commands\excel_writer.py", line 183, in add_filter_control
    xl.Workbooks.Open(file_path)
File "<COMObject <unknown>>", line 8, in Open
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, u'Microsoft Office Excel', u'Die Open-Methode des Workbooks-Objektes konnte nicht ausgef\xfchrt werden.', u'C:\\Program Files\\Microsoft Office\\OFFICE11\\1031\\xlmain11.chm', 0, -2146827284), None)

OK ... this is in German, but it basically says "the workbook open method could not be executed".

However, I can't work out why. Does anyone have any tips on how to find out why?

Cheers

ALJ

Here is some of the code and settings:

Spreadsheet creation code

...
w = xlwt.Workbook('UTF-8')
    worksheets = {} 

    data_formatting_dict = construct_data_formatting()

    for sheetref, sheetname, datasource, dataformat_ref in sheetlist:
        worksheets[sheetref] = w.add_sheet(sheetname)
        fetch_row_heights(sheetref, dataformat_ref)
        xls_set_columnwidth(sheetref, dataformat_ref)
        xls_set_main_titles(sheetref, sheetname, dataformat_ref)
        xls_set_titles(sheetref, sheetname, dataformat_ref)
        xls_insert_filter_row(sheetref, dataformat_ref)
        xls_freeze_panes(sheetref, dataformat_ref)
        xls_write_lines(sheetref,dataformat_ref,datasource,pre_title_rows+title_rows+post_title_rows)

    filename = fileroot + ".xls"
    archive = fileroot + ".zip"
    filepath = os.getcwd() + "\\" + filename
    w.save(filepath)

    add_filter_control(filepath)  << This is where the filter code is called.

    ziparchive(filename, archive)    
    full_archive_ref = save_to_folder + archive
    shutil.copy(archive, full_archive_ref)

    os.remove(filename)
    os.remove(archive)
...

add_filter_control

def add_filter_control(file_path):
    try: 
        from win32com.client import Dispatch
    except:
        return

    xl = Dispatch("Excel.Application") 
    xl.Workbooks.Open(file_path) 
    for id, sheetname, source, formatref in sheetlist:
        cellref = format_params[formatref]['filter_range']
        if cellref is not None:
            xl.ActiveWorkbook.Worksheets(sheetname).Range(cellref).AutoFilter(1)
    xl.ActiveWorkbook.Close(SaveChanges=1) # 1 is True, 0 is False
    xl.quit()

Task Scheduler Settings

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2010-07-23T21:25:09.4036437</Date>
    <Author>WIN-1CW6Q4GAAAM\Administrator</Author>
    <Description>Refreshes the temp tables in the database and generates the summary report spreadsheet.</Description>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2010-07-23T05:00:00</StartBoundary>
      <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>WIN-1CW6Q4GAAAM\Administrator</UserId>
      <LogonType>Password</LogonType>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <IdleSettings>
      <Duration>PT10M</Duration>
      <WaitTimeout>PT1H</WaitTimeout>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>run_reports.bat</Command>
      <WorkingDirectory>C:\www\my_site\mysite\</WorkingDirectory>
    </Exec>
  </Actions>
</Task>

After several days of searching I found the following solution (the full thread can be found at http://social.msdn.microsoft.com/Forums/en/innovateonoffice/thread/b81a3c4e-62db-488b-af06-44421818ef91 )

It would appear that a Desktop folder seems to be necessary in the systemprofile folder to open file by Excel. You need to create one of these folders:

Windows 2008 Server x64

C:\\Windows\\SysWOW64\\config\\systemprofile\\Desktop

Windows 2008 Server x86

C:\\Windows\\System32\\config\\systemprofile\\Desktop

I'm not sure why this is the case, but it worked for me. I hope that this is helpful for someone in the same situation and thanks to the guys who tried to help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM