I have automated the creation of a PowerPoint slide-deck via Python and have set-up a trigger in Task Scheduler for a daily report to be generated.
This is all fine while my computer is logged in, but the script fails when the setting: "Run whether is logged in or not".
I checked to see what line was at fault and it turns out it is this one:
Presentation.SaveAs('C:\\Users\\me\\Desktop\\test.pptx')
I am running Task Scheduler with highest priority but it only runs this task with the "User is logged in" state.
Below is the entire basic code segment for reference:
import win32com.client, MSO, MSPPT, sys, os
g = globals()
for c in dir(MSO.constants): g[c] = getattr(MSO.constants, c)
for c in dir(MSPPT.constants): g[c] = getattr(MSPPT.constants, c)
error_file = open('C:\\Users\\me\\Desktop\\error_file.txt', 'wb')
run = False
try:
Application = win32com.client.Dispatch("PowerPoint.Application")
Application.Visible = True
Presentation = Application.Presentations.Add()
Slide = Presentation.Slides.Add(1, ppLayoutBlank)
Presentation.SaveAs('C:\\Users\\me\\Desktop\\test.pptx')
Presentation.Close()
Application.Quit()
run = True
except:
run = False
if run == True:
error_file.write('ok')
else:
error_file.write('fail')
Any help on this would be much appreciated.
Thanks,
JP
Related
I have consulted several topics on the subject, but I didn't see any related to launching an app on a device directly using a ppadb command.
I managed to do this code:
import ppadb
import subprocess
from ppadb.client import Client as AdbClient
# Create the connect functiun
def connect():
client = AdbClient(host='localhost', port=5037)
devices = client.devices()
for device in devices:
print (device.serial)
if len(devices) == 0:
print('no device connected')
quit()
phone = devices[0]
print (f'connected to {phone.serial}')
return phone, client
if __name__ == '__main__':
phone, client = connect()
import time
time.sleep(5)
# How to print each app on the emulator
list = phone.list_packages()
for truc in list:
print(truc)
# Launch the desired app through phone.shell using the package name
phone.shell(????????????????)
From there, I have access to each app package (com.package.name). I would like to launch it through a phone.shell() command but I can't access the correct syntax.
I can execute a tap or a keyevent and it's perfectly working, but I want to be sure my code won't be disturbed by any change in position.
From How to start an application using Android ADB tools, the shell command to launch an app is
am start -n com.package.name/com.package.name.ActivityName
Hence you would call
phone.shell("am start -n com.package.name/com.package.name.ActivityName")
A given package may have multiple activities. To find out what they are, you can use dumpsys package as follows:
def parse_activities(package, connection, retval):
out = ""
while True:
data = connection.read(1024)
if not data: break
out += data.decode('utf-8')
retval.clear()
retval += [l.split()[-1] for l in out.splitlines() if package in l and "Activity" in l]
connection.close()
activities = []
phone.shell("dumpsys package", handler=lambda c: parse_activities("com.package.name", c, activities))
print(activities)
Here is the correct and easiest answer:
phone.shell('monkey -p com.package.name 1')
This method will launch the app without needing to have acces to the ActivityName
Using AndroidViewClient/cluebra, you can launch the MAIN Activity of a package as follows:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from com.dtmilano.android.viewclient import ViewClient
ViewClient.connectToDeviceOrExit()[0].startActivity(package='com.example.package')
This connects to the device (waiting if necessary) and then invokes startActivity() just using the package name.
startActivity() can also receive a component which is used when you know the package and the activity.
In my project I have to load data in database hourly .I tried celery and cron but found all the stuff very complicated and always createes some issue.I use pycharm in windows. I am new to django and just need a simple solution to run the following command hourly.
This loads data in dabase.
"python manage.py fetchfiles"
management/commands/fetchfiles
from django.core.management.base import BaseCommand, CommandError
from dashboard.models import airdata as tdata
import requests
import json
class Command(BaseCommand):
help = 'Fetches api data'
"""def add_arguments(self, parser):
none"""
def handle(self, *args, **options):
#for a in range(0,1578,10):
a = True
offno = 0
lst2=[]
dict1={}
while a == True:
api_key = "579b464db66ec23bdd000001cdd3946e44ce4aad7209ff7b23ac571b"
url = "https://api.data.gov.in/resource/3b01bcb8-0b14-4abf-b6f2-c1bfd384ba69?api-key={}&format=json&offset={}&limit=10".format(api_key,offno)
response = requests.get(url)
data = response.text
a1=json.loads(data)
for ele in a1['records']:
if ele['pollutant_min'] == 'NA':
dict1['pol_min'] = 0
else:
dict1['pol_min'] = int(ele['pollutant_min'])
if ele['pollutant_max'] == 'NA':
dict1['pol_max'] = 0
else:
dict1['pol_max'] = int(ele['pollutant_max'])
if ele['pollutant_avg'] == 'NA':
dict1['pol_avg'] = 0
else:
dict1['pol_avg'] = int(ele['pollutant_avg'])
dict1['state'] = ele['state']
dict1['city'] = ele['city']
dict1['station'] = ele['station']
dict1['time_vector'] = ele['last_update']
lst2.append(dict1.copy())
if a1["count"] < 10:
a= False
offno += 10
airx = json.dumps(lst2, indent=1)
tdata.objects.bulk_create([tdata(**vals) for vals in lst2])
return airx
You have 2 ways
Adding it to crontab on Unix systems or scheduled task on Windows.
Using Celery Beat
Celery is probably more complex than you need just to run something like his hourly. You've already discovered writing management commands. Just wrap the management command in a shell script and (on Unix/Linux) get cron to run it hourly. You need to make sure that the shell script stays "quiet" when it succeeds, but makes any failures very apparent so it's not sitting there failing with nobody noticing.
Can't advise what to do on Windows, but I think it has task scheduling.
I have a python script that reboot the local machine using the win32api package. but when i try to reboot a remote desktop the system crash and display the below error :
win32api.InitiateSystemShutdown(user, message, timeout, bForce, bReboot)
pywintypes.error: (5, 'InitiateSystemShutdown', 'Access is denied.')
what is the problem here and why i can't get the required privilege's yet we are on the same network?
code:
import win32security
import win32api
import sys
import time
from ntsecuritycon import *
def AdjustPrivilege(priv, enable=1):
# Get the process token
flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags)
# Get the ID for the system shutdown privilege.
idd = win32security.LookupPrivilegeValue(None, priv)
# Now obtain the privilege for this process.
# Create a list of the privileges to be added.
if enable:
newPrivileges = [(idd, SE_PRIVILEGE_ENABLED)]
else:
newPrivileges = [(idd, 0)]
# and make the adjustment
win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)
def RebootServer(user=None,message='Rebooting', timeout=30, bForce=0, bReboot=1):
AdjustPrivilege(SE_SHUTDOWN_NAME)
try:
win32api.InitiateSystemShutdown(user, message, timeout, bForce, bReboot)
finally:
# Now we remove the privilege we just added.
AdjustPrivilege(SE_SHUTDOWN_NAME, 0)
def AbortReboot():
AdjustPrivilege(SE_SHUTDOWN_NAME)
try:
win32api.AbortSystemShutdown(None)
finally:
AdjustPrivilege(SE_SHUTDOWN_NAME, 0)
#test the functions:
# Reboot computer
RebootServer("XXX.XXX.XX.XX")
# Wait 10 seconds
time.sleep(10)
print ('Aborting shutdown')
# Abort shutdown before its execution
AbortReboot()
Have you tried turning it off and on again? (Sorry)
You could try setting the owner of the script to an Administrator by right-clicking the file and selecting Preferences. You can also try running the python executable as an administrator.
I am looking for some Python code to create a Windows Task in the Task Scheduler, it needs to run at start & have the highest permissions level (admin).
// description of your code here
Uses the new COM Task Scheduler Interface to create a new disabled scheduled task, then run it once as part of a script. Use this to launch interactive tasks, even remotely.
import win32com.client
computer_name = "" #leave all blank for current computer, current user
computer_username = ""
computer_userdomain = ""
computer_password = ""
action_id = "Test Task" #arbitrary action ID
action_path = r"c:\windows\system32\calc.exe" #executable path (could be python.exe)
action_arguments = r'' #arguments (could be something.py)
action_workdir = r"c:\windows\system32" #working directory for action executable
author = "Someone" #so that end users know who you are
description = "testing task" #so that end users can identify the task
task_id = "Test Task"
task_hidden = False #set this to True to hide the task in the interface
username = ""
password = ""
run_flags = "TASK_RUN_NO_FLAGS" #see dict below, use in combo with username/password
#define constants
TASK_TRIGGER_DAILY = 2
TASK_CREATE = 2
TASK_CREATE_OR_UPDATE = 6
TASK_ACTION_EXEC = 0
IID_ITask = "{148BD524-A2AB-11CE-B11F-00AA00530503}"
RUNFLAGSENUM = {
"TASK_RUN_NO_FLAGS" : 0,
"TASK_RUN_AS_SELF" : 1,
"TASK_RUN_IGNORE_CONSTRAINTS" : 2,
"TASK_RUN_USE_SESSION_ID" : 4,
"TASK_RUN_USER_SID" : 8
}
#connect to the scheduler (Vista/Server 2008 and above only)
scheduler = win32com.client.Dispatch("Schedule.Service")
scheduler.Connect(computer_name or None, computer_username or None, computer_userdomain or None, computer_password or None)
rootFolder = scheduler.GetFolder("\\")
#(re)define the task
taskDef = scheduler.NewTask(0)
colTriggers = taskDef.Triggers
trigger = colTriggers.Create(TASK_TRIGGER_DAILY)
trigger.DaysInterval = 100
trigger.StartBoundary = "2100-01-01T08:00:00-00:00" #never start
trigger.Enabled = False
colActions = taskDef.Actions
action = colActions.Create(TASK_ACTION_EXEC)
action.ID = action_id
action.Path = action_path
action.WorkingDirectory = action_workdir
action.Arguments = action_arguments
info = taskDef.RegistrationInfo
info.Author = author
info.Description = description
settings = taskDef.Settings
settings.Enabled = False
settings.Hidden = task_hidden
#register the task (create or update, just keep the task name the same)
result = rootFolder.RegisterTaskDefinition(task_id, taskDef, TASK_CREATE_OR_UPDATE, "", "", RUNFLAGSENUM[run_flags] ) #username, password
#run the task once
task = rootFolder.GetTask(task_id)
task.Enabled = True
runningTask = task.Run("")
task.Enabled = False
This code creates a task to run daily, but not at login & not as admin. Is there any way I can do this without requiring the UAC Prompt to open at startup?
EDIT: I am NOT looking to just make the program ask for administrator, as the prompt will popup, as specified above. I need it to have the highest execution level in the WINDOWS EVENT SCHEDULER to run at logon.
I think it would be a good idea for you to build a Batch file running python and your script. Having done that there are a few things that you might want to try, i haven't personally had the time to try them out but here you go:
Compile the .BAT file and make it an .exe once you do that i think you should be able to involve your task scheduler into the mix and get your code running whenever you need.
If nothing works you can always mess around with your window's registry to allow your script to bypass the prompt using a Windows Registry Editor.
Do look it up before you execute as this is code I have found elsewhere, but it should do the trick:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{E2F13B98-650F-47DB-845A-420A1ED34EC7}User\Software\Microsoft\Windows\CurrentVersion\Policies\Associations]
"LowRiskFileTypes"=".exe;.bat;.cmd;.vbs"
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Associations]
"LowRiskFileTypes"=".exe;.bat;.cmd;.vbs"
After searching Google more thoroughly, I came across a command that does exactly what I need.
schtasks.exe /create /S COMPUTERNAME /RU "NT AUTHORITY\SYSTEM" /RL HIGHEST /SC ONLOGON /TN "Administrative OnLogon Script" /TR "cscript.exe \"Path\To\Script.vbs\""
All I need to do is replace the computer name, and program to execute and it makes the task perfectly. I can execute it in a elevated Python environment to create it.
I'm studying vCenter 6.5 and community samples help a lot, but in this particular situation I can't figure out, what's going on. The script:
from __future__ import with_statement
import atexit
from tools import cli
from pyVim import connect
from pyVmomi import vim, vmodl
def get_args():
*Boring args parsing works*
return args
def main():
args = get_args()
try:
service_instance = connect.SmartConnectNoSSL(host=args.host,
user=args.user,
pwd=args.password,
port=int(args.port))
atexit.register(connect.Disconnect, service_instance)
content = service_instance.RetrieveContent()
vm = content.searchIndex.FindByUuid(None, args.vm_uuid, True)
creds = vim.vm.guest.NamePasswordAuthentication(
username=args.vm_user, password=args.vm_pwd
)
try:
pm = content.guestOperationsManager.processManager
ps = vim.vm.guest.ProcessManager.ProgramSpec(
programPath=args.path_to_program,
arguments=args.program_arguments
)
res = pm.StartProgramInGuest(vm, creds, ps)
if res > 0:
print "Program executed, PID is %d" % res
except IOError, e:
print e
except vmodl.MethodFault as error:
print "Caught vmodl fault : " + error.msg
return -1
return 0
# Start program
if __name__ == "__main__":
main()
When I execute it in console, it successfully connects to the target virtual machine and prints
Program executed, PID is 2036
In task manager I see process with mentioned PID, it was created by the correct user, but there is no GUI of the process (calc.exe). RMB click does not allow to "Expand" the process.
I suppose, that this process was created with special parameters, maybe in different session.
In addition, I tried to run batch file to check if it actually executes, but the answer is no, batch file does not execute.
Any help, advices, clues would be awesome.
P.S. I tried other scripts and successfully transferred a file to the VM.
P.P.S. Sorry for my English.
Update: All such processes start in session 0.
Have you tried interactiveSession ?
https://github.com/vmware/pyvmomi/blob/master/docs/vim/vm/guest/GuestAuthentication.rst
This boolean argument passed to NamePasswordAuthentication and means the following:
This is set to true if the client wants an interactive session in the guest.