; -- CodeAutomation2.iss -- ; ; This script shows how to use IUnknown based COM Automation objects. ; ; Note: some unneeded interface functions which had special types have been replaced ; by dummies to avoid having to define those types. Do not remove these dummies as ; that would change the function indices which is bad. Also, not all function ; protoypes have been tested, only those used by this example. [Setup] AppName=My Program AppVersion=1.5 WizardStyle=modern DisableWelcomePage=no CreateAppDir=no DisableProgramGroupPage=yes DefaultGroupName=My Program UninstallDisplayIcon={app}\MyProg.exe OutputDir=userdocs:Inno Setup Examples Output [Code] {--- IShellLink ---} const CLSID_ShellLink = '{00021401-0000-0000-C000-000000000046}'; type IShellLinkW = interface(IUnknown) '{000214F9-0000-0000-C000-000000000046}' procedure Dummy; procedure Dummy2; procedure Dummy3; function GetDescription(pszName: String; cchMaxName: Integer): HResult; function SetDescription(pszName: String): HResult; function GetWorkingDirectory(pszDir: String; cchMaxPath: Integer): HResult; function SetWorkingDirectory(pszDir: String): HResult; function GetArguments(pszArgs: String; cchMaxPath: Integer): HResult; function SetArguments(pszArgs: String): HResult; function GetHotkey(var pwHotkey: Word): HResult; function SetHotkey(wHotkey: Word): HResult; function GetShowCmd(out piShowCmd: Integer): HResult; function SetShowCmd(iShowCmd: Integer): HResult; function GetIconLocation(pszIconPath: String; cchIconPath: Integer; out piIcon: Integer): HResult; function SetIconLocation(pszIconPath: String; iIcon: Integer): HResult; function SetRelativePath(pszPathRel: String; dwReserved: DWORD): HResult; function Resolve(Wnd: HWND; fFlags: DWORD): HResult; function SetPath(pszFile: String): HResult; end; IPersist = interface(IUnknown) '{0000010C-0000-0000-C000-000000000046}' function GetClassID(var classID: TGUID): HResult; end; IPersistFile = interface(IPersist) '{0000010B-0000-0000-C000-000000000046}' function IsDirty: HResult; function Load(pszFileName: String; dwMode: Longint): HResult; function Save(pszFileName: String; fRemember: BOOL): HResult; function SaveCompleted(pszFileName: String): HResult; function GetCurFile(out pszFileName: String): HResult; end; procedure IShellLinkButtonOnClick(Sender: TObject); var Obj: IUnknown; SL: IShellLinkW; PF: IPersistFile; begin { Create the main ShellLink COM Automation object } Obj := CreateComObject(StringToGuid(CLSID_ShellLink)); { Set the shortcut properties } SL := IShellLinkW(Obj); OleCheck(SL.SetPath(ExpandConstant('{srcexe}'))); OleCheck(SL.SetArguments('')); OleCheck(SL.SetShowCmd(SW_SHOWNORMAL)); { Save the shortcut } PF := IPersistFile(Obj); OleCheck(PF.Save(ExpandConstant('{autodesktop}\CodeAutomation2 Test.lnk'), True)); MsgBox('Saved a shortcut named ''CodeAutomation2 Test'' on the common desktop.', mbInformation, mb_Ok); end; {--- ITaskScheduler ---} const CLSID_TaskScheduler = '{148BD52A-A2AB-11CE-B11F-00AA00530503}'; CLSID_Task = '{148BD520-A2AB-11CE-B11F-00AA00530503}'; IID_Task = '{148BD524-A2AB-11CE-B11F-00AA00530503}'; TASK_TIME_TRIGGER_DAILY = 1; type ITaskScheduler = interface(IUnknown) '{148BD527-A2AB-11CE-B11F-00AA00530503}' function SetTargetComputer(pwszComputer: String): HResult; function GetTargetComputer(out ppwszComputer: String): HResult; procedure Dummy; function Activate(pwszName: String; var riid: TGUID; out ppUnk: IUnknown): HResult; function Delete(pwszName: String): HResult; function NewWorkItem(pwszTaskName: String; var rclsid: TGUID; var riid: TGUID; out ppUnk: IUnknown): HResult; procedure Dummy2; function IsOfType(pwszName: String; var riid: TGUID): HResult; end; TDaily = record DaysInterval: WORD; end; TWeekly = record WeeksInterval: WORD; rgfDaysOfTheWeek: WORD; end; TMonthyDate = record rgfDays: DWORD; rgfMonths: WORD; end; TMonthlyDow = record wWhichWeek: WORD; rgfDaysOfTheWeek: WORD; rgfMonths: WORD; end; { ROPS doesn't support unions, replace this with the type you need and adjust padding (end size has to be 48). } TTriggerTypeUnion = record Daily: TDaily; Pad1: WORD; Pad2: WORD; Pad3: WORD; end; TTaskTrigger = record cbTriggerSize: WORD; Reserved1: WORD; wBeginYear: WORD; wBeginMonth: WORD; wBeginDay: WORD; wEndYear: WORD; wEndMonth: WORD; wEndDay: WORD; wStartHour: WORD; wStartMinute: WORD; MinutesDuration: DWORD; MinutesInterval: DWORD; rgFlags: DWORD; TriggerType: DWORD; Type_: TTriggerTypeUnion; Reserved2: WORD; wRandomMinutesInterval: WORD; end; ITaskTrigger = interface(IUnknown) '{148BD52B-A2AB-11CE-B11F-00AA00530503}' function SetTrigger(var pTrigger: TTaskTrigger): HResult; function GetTrigger(var pTrigger: TTaskTrigger): HResult; function GetTriggerString(var ppwszTrigger: String): HResult; end; IScheduledWorkItem = interface(IUnknown) '{A6B952F0-A4B1-11D0-997D-00AA006887EC}' function CreateTrigger(out piNewTrigger: Word; out ppTrigger: ITaskTrigger): HResult; function DeleteTrigger(iTrigger: Word): HResult; function GetTriggerCount(out pwCount: Word): HResult; function GetTrigger(iTrigger: Word; var ppTrigger: ITaskTrigger): HResult; function GetTriggerString(iTrigger: Word; out ppwszTrigger: String): HResult; procedure Dummy; procedure Dummy2; function SetIdleWait(wIdleMinutes: Word; wDeadlineMinutes: Word): HResult; function GetIdleWait(out pwIdleMinutes: Word; out pwDeadlineMinutes: Word): HResult; function Run: HResult; function Terminate: HResult; function EditWorkItem(hParent: HWND; dwReserved: DWORD): HResult; procedure Dummy3; function GetStatus(out phrStatus: HResult): HResult; function GetExitCode(out pdwExitCode: DWORD): HResult; function SetComment(pwszComment: String): HResult; function GetComment(out ppwszComment: String): HResult; function SetCreator(pwszCreator: String): HResult; function GetCreator(out ppwszCreator: String): HResult; function SetWorkItemData(cbData: Word; var rgbData: Byte): HResult; function GetWorkItemData(out pcbData: Word; out prgbData: Byte): HResult; function SetErrorRetryCount(wRetryCount: Word): HResult; function GetErrorRetryCount(out pwRetryCount: Word): HResult; function SetErrorRetryInterval(wRetryInterval: Word): HResult; function GetErrorRetryInterval(out pwRetryInterval: Word): HResult; function SetFlags(dwFlags: DWORD): HResult; function GetFlags(out pdwFlags: DWORD): HResult; function SetAccountInformation(pwszAccountName: String; pwszPassword: String): HResult; function GetAccountInformation(out ppwszAccountName: String): HResult; end; ITask = interface(IScheduledWorkItem) '{148BD524-A2AB-11CE-B11F-00AA00530503}' function SetApplicationName(pwszApplicationName: String): HResult; function GetApplicationName(out ppwszApplicationName: String): HResult; function SetParameters(pwszParameters: String): HResult; function GetParameters(out ppwszParameters: String): HResult; function SetWorkingDirectory(pwszWorkingDirectory: String): HResult; function GetWorkingDirectory(out ppwszWorkingDirectory: String): HResult; function SetPriority(dwPriority: DWORD): HResult; function GetPriority(out pdwPriority: DWORD): HResult; function SetTaskFlags(dwFlags: DWORD): HResult; function GetTaskFlags(out pdwFlags: DWORD): HResult; function SetMaxRunTime(dwMaxRunTimeMS: DWORD): HResult; function GetMaxRunTime(out pdwMaxRunTimeMS: DWORD): HResult; end; procedure ITaskSchedulerButtonOnClick(Sender: TObject); var Obj, Obj2: IUnknown; TaskScheduler: ITaskScheduler; G1, G2: TGUID; Task: ITask; iNewTrigger: WORD; TaskTrigger: ITaskTrigger; TaskTrigger2: TTaskTrigger; PF: IPersistFile; begin { Create the main TaskScheduler COM Automation object } Obj := CreateComObject(StringToGuid(CLSID_TaskScheduler)); { Create the Task COM automation object } TaskScheduler := ITaskScheduler(Obj); G1 := StringToGuid(CLSID_Task); G2 := StringToGuid(IID_Task); //This will throw an exception if the task already exists OleCheck(TaskScheduler.NewWorkItem('CodeAutomation2 Test', G1, G2, Obj2)); { Set the task properties } Task := ITask(Obj2); OleCheck(Task.SetComment('CodeAutomation2 Test Comment')); OleCheck(Task.SetApplicationName(ExpandConstant('{srcexe}'))); { Set the task account information } //Uncomment the following and provide actual user info to get a runnable task //OleCheck(Task.SetAccountInformation('username', 'password')); { Create the TaskTrigger COM automation object } OleCheck(Task.CreateTrigger(iNewTrigger, TaskTrigger)); { Set the task trigger properties } with TaskTrigger2 do begin cbTriggerSize := SizeOf(TaskTrigger2); wBeginYear := 2009; wBeginMonth := 10; wBeginDay := 1; wStartHour := 12; TriggerType := TASK_TIME_TRIGGER_DAILY; Type_.Daily.DaysInterval := 1; end; OleCheck(TaskTrigger.SetTrigger(TaskTrigger2)); { Save the task } PF := IPersistFile(Obj2); OleCheck(PF.Save('', True)); MsgBox('Created a daily task named named ''CodeAutomation2 Test''.' + #13#13 + 'Note: Account information not set so the task won''t actually run, uncomment the SetAccountInfo call and provide actual user info to get a runnable task.', mbInformation, mb_Ok); end; {---} procedure CreateButton(ALeft, ATop: Integer; ACaption: String; ANotifyEvent: TNotifyEvent); begin with TButton.Create(WizardForm) do begin Left := ALeft; Top := ATop; Width := (WizardForm.CancelButton.Width*3)/2; Height := WizardForm.CancelButton.Height; Caption := ACaption; OnClick := ANotifyEvent; Parent := WizardForm.WelcomePage; end; end; procedure InitializeWizard(); var Left, LeftInc, Top, TopInc: Integer; begin Left := WizardForm.WelcomeLabel2.Left; LeftInc := (WizardForm.CancelButton.Width*3)/2 + ScaleX(8); TopInc := WizardForm.CancelButton.Height + ScaleY(8); Top := WizardForm.WelcomeLabel2.Top + WizardForm.WelcomeLabel2.Height - 4*TopInc; CreateButton(Left, Top, '&IShellLink...', @IShellLinkButtonOnClick); Top := Top + TopInc; CreateButton(Left, Top, '&ITaskScheduler...', @ITaskSchedulerButtonOnClick); end;