word.saveas() - ' nonepy'对象没有属性' saveas' - 当任务调度程序运行时

发布于 2025-02-08 00:40:51 字数 5158 浏览 2 评论 0原文

我遇到了一个奇怪的问题,我对可能发生的事情感到非常迷失。一般背景是我要循环通过一个文件夹,然后将所有“ .docx”文件转换为“ .pdf”文件。令人困惑的部分是,当我输入循环的时,当通过Windows Task Scheduler触发而无需明确重新编写文件路径时,它不再正常工作。我将Windows任务调度程序用作用户(管理权),并具有最高特权的登录或关闭状态。这是我在手动触发时使用的用户。这是在RDP服务器上。

以下是更多详细信息:

脚本1:使用Task Scheduler

from win32com import client
import os
import sys

#import Custom Classes
Classes = r'C:\Python_Solutions\Classes'

#Direct import to Class file
sys.path.insert(0,Classes)

import Classes

#Declare jobName
jobName = 'pdfsave'
logFolderLocation = r'C:\Python_Solutions\Notice_Form_Generation\pdftest'

#Create Log Folder
Classes.Atlas.createTextJobLog(jobName, logFolderLocation)

try:
    print('before')
    for file in os.listdir(r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt'):
        print(str(file))
        if '.docx' in file:
            filepath = r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt\\' + file
            print('Converting to .pdf: ' + filepath)
            endFilePath_pdf = filepath[:-4] + 'pdf'
            print('here1')
            word = client.DispatchEx("Word.Application")
            print('here2')
            worddoc = word.Documents.Open(filepath, ReadOnly=1)
            print('here3')
            worddoc.SaveAs(endFilePath_pdf, FileFormat=17)
            print('here4')
            worddoc.Close()
            print('here5')
            word.Quit()
            print('here6')
except Exception as e:
    print(str(e))

脚本2触发时工作时工作2:在我自己触发或运行脚本时工作,但是错误'nontype'对象没有属性'saveas' ,当我使用任务调度程序运行时。我很困惑这是怎么回事,正如您在代码中看到的那样,我正在仔细检查文件路径,以确保它们正确地进入函数,但不想工作。.

它在之后断开 。 here3.saveas()函数:

from win32com import client
import os
import sys

#import Custom Classes
Classes = r'C:\Python_Solutions\Classes'

#Direct import to Class file
sys.path.insert(0,Classes)

import Classes


#Declare jobName
jobName = 'pdfsave_simple2'
logFolderLocation = r'C:\Python_Solutions\Notice_Form_Generation\pdftest'


# In[ ]:


#Create Log Folder
Classes.Atlas.createTextJobLog(jobName, logFolderLocation)

folder = r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt'

try:
    print('before')
    for file in os.listdir(folder):
        print(str(file))
        if '.docx' in file:
            filepath = folder + '\\' + file
            print('Converting to .pdf: ' + filepath)
            endFilePath_pdf = filepath[:-4] + 'pdf'
            print('here1')
            word = client.DispatchEx("Word.Application")
            print('here2')

            print(os.path.abspath(filepath))
            print(os.path.abspath(endFilePath_pdf))

            worddoc = word.Documents.Open(filepath, ReadOnly=1)
            print('here3')
            worddoc.SaveAs(endFilePath_pdf, FileFormat=17)  # <-- here3
            print('here4')
            worddoc.Close()
            print('here5')
            word.Quit()
            print('here6')
except Exception as e:
    print(str(e))
    sys.stdout.close()
    sys.exit()

我尝试使用脚本2:

---将ABS路径添加到函数中(我得到相同错误):

worddoc = word.Documents.Open(os.path.abspath(filepath), ReadOnly=1)
worddoc.SaveAs(os.path.abspath(endFilePath_pdf), FileFormat=17)

----------------在发送到单词函数之前,请使用r'example \ example重新创建文件路径(在我手动尝试运行时,这实际上会出现相同的错误):

filepath = "r'" + os.path.abspath(filepath) + "'"
endFilePath_pdf = "r'" + os.path.abspath(endFilePath_pdf) + "'"

---当我检查目录时,它们当我手动运行和使用调度程序运行时,两者都一样:

pathlib.Path(__file__).parent.resolve()

我相信这是错误的,任何人都可以

在本地尝试以下尝试时提供帮助(下面详细介绍),我会得到:

            print('cwd: ' + str(os.path.abspath(os.getcwd())))
            print('script run: ' + str(pathlib.Path(__file__).parent.resolve()))
  • cwd:c:\ python_solutions \ notes _form_generation \ pdftest
  • 脚本运行:c:\ python_solutions \ nots_form_generation \ pdftest \ pdftest

当我使用任务调度程序运行时,我获得

  • CWD:c:\ windows c:\ windows \ system32
  • 脚本运行:c:\ python_solutions \ notes _form_generation \ pdftest

我更改了CWD,但仍然得到相同的nontype错误:

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

我缺少某些东西吗?对我来说,这是非常奇怪的,我在两种情况下都将相同的精确字符串输入到该函数中,甚至在手动触发时可以工作,但是当通过任务调度程序触发时,我会得到nontype错误!我不知道会发生什么,在使用任务调度程序运行时,我必须以某种方式更具体地编写路径?或者,也许在进入它之前确保我在正确的CWD中?我很傻,因为我发现它在for循环中编写文件路径时发现它有效,但是我需要通过多个文件夹迭代,因此我需要能够明确编写中的文件夹路径> >环形。我正在使用循环来浏览许多文件夹和文件(在此脚本的较大规模中)。

更新 - 我尝试使用comtypes.client,并且在步骤3之前使用NULL COM POINTER访问失败

            print('1')
            word = comtypes.client.CreateObject('Word.Application')
            print('2')
            doc = word.Documents.Open(filepath)
            print('3')
            doc.SaveAs(endFilePath_pdf, FileFormat=17)
            print('4')
            doc.Close()
            print('1')
            word.Quit()
    ```

I'm running into a strange problem and I'm very lost on what could be happening. The general background is I'm looping through a folder and converting all the '.docx' files into '.pdf' files. The part that is confusing is that when I enter the for loop, it no longer works correctly when trigger via Windows Task Scheduler without explicitly re-writing the file path. I am using the Windows Task Scheduler as my user (Admin rights) and with logged on or off status, with highest privilege's. This is the same user I'm using when triggering manually. This is on an RDP server.

Here is more details below:

Script 1: Works when triggered with Task Scheduler

from win32com import client
import os
import sys

#import Custom Classes
Classes = r'C:\Python_Solutions\Classes'

#Direct import to Class file
sys.path.insert(0,Classes)

import Classes

#Declare jobName
jobName = 'pdfsave'
logFolderLocation = r'C:\Python_Solutions\Notice_Form_Generation\pdftest'

#Create Log Folder
Classes.Atlas.createTextJobLog(jobName, logFolderLocation)

try:
    print('before')
    for file in os.listdir(r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt'):
        print(str(file))
        if '.docx' in file:
            filepath = r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt\\' + file
            print('Converting to .pdf: ' + filepath)
            endFilePath_pdf = filepath[:-4] + 'pdf'
            print('here1')
            word = client.DispatchEx("Word.Application")
            print('here2')
            worddoc = word.Documents.Open(filepath, ReadOnly=1)
            print('here3')
            worddoc.SaveAs(endFilePath_pdf, FileFormat=17)
            print('here4')
            worddoc.Close()
            print('here5')
            word.Quit()
            print('here6')
except Exception as e:
    print(str(e))

Script 2: Works when I trigger or run the script myself, but fails with the error 'NoneType' object has no attribute 'SaveAs', when I run with the task scheduler. I am confused how this could be, as you can see in the code, I am double checking the file paths to make sure they are being fed into the functions correctly but it doesn't want to work..

It breaks after here3 during the .SaveAs() function:

from win32com import client
import os
import sys

#import Custom Classes
Classes = r'C:\Python_Solutions\Classes'

#Direct import to Class file
sys.path.insert(0,Classes)

import Classes


#Declare jobName
jobName = 'pdfsave_simple2'
logFolderLocation = r'C:\Python_Solutions\Notice_Form_Generation\pdftest'


# In[ ]:


#Create Log Folder
Classes.Atlas.createTextJobLog(jobName, logFolderLocation)

folder = r'C:\Python_Solutions\Notice_Form_Generation\Local\2022-01-01\1_FixedPrem1stAttempt'

try:
    print('before')
    for file in os.listdir(folder):
        print(str(file))
        if '.docx' in file:
            filepath = folder + '\\' + file
            print('Converting to .pdf: ' + filepath)
            endFilePath_pdf = filepath[:-4] + 'pdf'
            print('here1')
            word = client.DispatchEx("Word.Application")
            print('here2')

            print(os.path.abspath(filepath))
            print(os.path.abspath(endFilePath_pdf))

            worddoc = word.Documents.Open(filepath, ReadOnly=1)
            print('here3')
            worddoc.SaveAs(endFilePath_pdf, FileFormat=17)  # <-- here3
            print('here4')
            worddoc.Close()
            print('here5')
            word.Quit()
            print('here6')
except Exception as e:
    print(str(e))
    sys.stdout.close()
    sys.exit()

Things I have tried with Script 2:

--- Adding the abs path into the function (I get the same error):

worddoc = word.Documents.Open(os.path.abspath(filepath), ReadOnly=1)
worddoc.SaveAs(os.path.abspath(endFilePath_pdf), FileFormat=17)

--- Tried to recreate the file path with the r'example\example before sending into the word functions (This actually broke with the same error when I tried running manually):

filepath = "r'" + os.path.abspath(filepath) + "'"
endFilePath_pdf = "r'" + os.path.abspath(endFilePath_pdf) + "'"

--- When I check the directory, they are both the same when I run manually and when I run with the scheduler:

pathlib.Path(__file__).parent.resolve()

I believe this is what is wrong, can anyone help (detailed below)

When I tried the following locally, I get:

            print('cwd: ' + str(os.path.abspath(os.getcwd())))
            print('script run: ' + str(pathlib.Path(__file__).parent.resolve()))
  • cwd: C:\Python_Solutions\Notice_Form_Generation\pdftest
  • script run: C:\Python_Solutions\Notice_Form_Generation\pdftest

When I run with the Task Scheduler, I get

  • cwd: C:\Windows\system32
  • script run: C:\Python_Solutions\Notice_Form_Generation\pdftest

I changed the cwd with the following and still get the same NoneType error:

abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)

Is there something I am missing? It is so strange to me that I am inputting the same exact string into the function in both circumstances, and it even works when triggered manually, but when triggered through the task scheduler I get the NoneType error! I have no idea what could be going on, do I have to write the path more specifically somehow when am running with task scheduler? Or maybe make sure I am in the right cwd before going into it? I am dumbfounded because I found it works when I write the file path in the for loop, but I need to iterate through multiple folders, so I need the ability to not write explicitly the folder path in the for loop. I am using the loop to get through many folders and files (in the larger scale case of this script).

Update - I tried using comtypes.client and it fails with NULL COM pointer access before step 3

            print('1')
            word = comtypes.client.CreateObject('Word.Application')
            print('2')
            doc = word.Documents.Open(filepath)
            print('3')
            doc.SaveAs(endFilePath_pdf, FileFormat=17)
            print('4')
            doc.Close()
            print('1')
            word.Quit()
    ```

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半窗疏影 2025-02-15 00:40:51

我知道这是一篇旧帖子,但是当使用计划任务时,我遇到了相同的非类型错误,该任务与运行Python的用户记录以将DOCX保存为Windows Server 2022和Windows 10 Pro上的PDF。

奇怪的是,它在Windows 11上正常工作。

不幸的是,我还没有弄清楚原因。感谢OP确认我没有失去理智。如果我找到解决方案,将更新。

I know this is an old post, but I am having the same NoneType error when using a scheduled task as logged off user that runs python to save a docx as a PDF on Windows Server 2022 and Windows 10 Pro.

Oddly, it is working as expected on Windows 11.

Unfortunately, I have not yet figured out why. Thanks to OP for confirming I was not losing my mind. Will update if I find solution.

吃→可爱长大的 2025-02-15 00:40:51

我已经通过修改docx2pdf init .py:

导入的pythoncom,然后在“ windows”方法中修改了这个问题,然后我添加了pythoncom.coinitialize()作为两个savesas呼叫的参数。

I have solved this issue by modifying docx2pdf init.py:

Imported pythoncom, then in the "windows" method i have added pythoncom.CoInitialize() as argument to both SavesAs calls.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文