Extract Current Date and assign to variable in FTP Scripter (Pascal Environment) - ftp

I am using FTP Scripter (Base - Pascal) to create some scripts.
I have a requirement to create the folders based on current date.
Below is my code :-
var
mydate: String;
today : TDateTime;
LocalArchive: String;
begin
today := Now;
mydate := FormatDateTime('ddmmyyyy', today);
LocalArchive := 'D:\FOR TPA Archive\' + date;
end;
While compiling the above code, I am getting below error. PFB the screenshot for the same.
Can someone please help in fixing the above error.
I am using FTP Scripter which comes with Syncplify Software.
Thanks

Related

Delphi: how can i get list of running applications with starting path?

Using Delphi (windows app) i want to get list of other applications running currently. Here How to check if a process is running using Delphi? i've found great tutorial about geting filenames/names of running application, however it gives names only process name (for example NOTEPAD.EXE). I've used naturally part with
UpperCase(ExtractFileName(FProcessEntry32.szExeFile))
and
UpperCase(ExtractFilePath(FProcessEntry32.szExeFile))
and just
UpperCase(FProcessEntry32.szExeFile)
but obviously FProcessEntry32.szExeFile does not have a path to file/process
Is there a simply way of getting list with paths? Here's How to get the list of running processes including full file path? solution with JclSysInfo library, but i cant use it in place of work in project.
I looked at what I could in Google and what I found usually concerned just the application that is running or the application that is active, but I can't just find a list of all running applications. Maybe i'm missing something obvious?
I'm not looking for any complex procedures, I'm not much interested in process parrent, or if there is no access to the process path, I don't have it and don't bother.
Any simple hint?
OK, due to helpfull comment from #TLama i've combined topics above to take name and path of process:
function processExists(exeFileName: string): Boolean;
var
ContinueLoopP, ContinueLoopM: BOOL;
FSnapshotHandle1, FSnapshotHandle2: THandle;
FProcessEntry32: TProcessEntry32;
FMODULEENTRY32: TMODULEENTRY32;
begin
FSnapshotHandle1 := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
FMODULEENTRY32.dwSize := SizeOf(FMODULEENTRY32);
ContinueLoopP := Process32First(FSnapshotHandle1, FProcessEntry32);
ContinueLoopM := Module32First(FSnapshotHandle2, FMODULEENTRY32);
Result := False;
while Integer(ContinueLoopP) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
UpperCase(ExeFileName))) then
Result := True;
ShowMessage(FMODULEENTRY32.szExePath + FProcessEntry32.szExeFile);
ContinueLoopP := Process32Next(FSnapshotHandle1, FProcessEntry32);
ContinueLoopM := Module32Next(FSnapshotHandle2, FMODULEENTRY32);
end;
CloseHandle(FSnapshotHandle1);
CloseHandle(FSnapshotHandle2);
end;
But still FProcessEntry32.szExeFile returns empty string. What i'm doing wrong? Thank You in advance.
I cannot write comment (low score), so I need to write as "answer". Try this code,
using FProcessEntry32.th32ProcessID as parameter:
Function QueryFullProcessImageNameW(hProcess:THandle; dwFlags:Cardinal; lpExeName:PWideChar; Var lpdwSize:Cardinal) : Boolean; StdCall; External 'Kernel32.dll' Name 'QueryFullProcessImageNameW';
Function GetFullPath(Pid:Cardinal) : UnicodeString;
Var rLength:Cardinal;
Handle:THandle;
Begin Result:='';
Handle:=OpenProcess(PROCESS_QUERY_INFORMATION, False, Pid);
If Handle = INVALID_HANDLE_VALUE Then Exit;
rLength:=256; // allocation buffer
SetLength(Result, rLength+1); // for trailing space
If Not QueryFullProcessImageNameW(Handle, 0, #Result[1],rLength) Then Result:='' Else SetLength(Result, rLength);
End;
This is a simple way I think. If you want to get the loaded DLL's full name, use
FMODULEENTRY32.hModule with GetModuleFileNameW function.

Indy HttpClient.Post gives range check error when built for release but not in debug - why?

I am using Delphi 2009, Indy ver 10.5498 together with libeay32.dll and ssleay32.dll from the zip file openssl-1.0.2r-i386-win32 at https://indy.fulgan.com/SSL/.
Range checking is turned on in project options and not turned off anywhere.
Using the code below, which I generated with Remy's help from this post, I can upload data to an API on a server via https when running in the IDE with debugging turned on or from a compiled exe generated with debugging tuned on.
However, if I build a release version then whether I run it through the IDE or as an exe I get a range check error on the line result := HttpClient.Post(THE_URL, FormData);
The params list simply contains the to, from, subject, body etc and there is no attachment in the filenames list ie filenames.Count = 0. U_GeneralRoutines.TheFileStoreFolder is simply a folder inside ProgramData where the SSL DLL's are stored.
As the debugger didn't catch this I put in the two showmessage lines before and after the call. When built as debug, both messages get shown and the post succeeds. When built as release the first one gets displayed and then I get the range check error.
I don't suppose there is a bug in the POST code, so what can be going wrong?
function UploadToAPI(params, filenames: TStrings): string;
var
HttpClient: TIdHttp;
IdSSLIOHandler: TIdSSLIOHandlerSocketOpenSSL;
FormData : TIdMultiPartFormDataStream;
i : integer;
PathToSSLlibraries : string;
begin
FormData := TIdMultiPartFormDataStream.Create;
HttpClient:= TIdHttp.Create;
IdSSLIOHandler:= TIdSSLIOHandlerSocketOpenSSL.Create;
PathToSSLlibraries := IncludeTrailingPathDelimiter(U_GeneralRoutines.TheFileStoreFolder);
IdOpenSSLSetLibPath(PathToSSLlibraries); //set path to libeay32.dll and ssleay32.dll in the common ProgramData folder
HttpClient.IOHandler := IdSSLIOHandler;
HttpClient.Request.CustomHeaders.FoldLines := true ;
try
for i := 0 to params.Count - 1 do
FormData.AddFormField(params.Names[i], params.ValueFromIndex[i]);
for i := 0 to filenames.Count - 1 do
FormData.AddFile('attachment', filenames[i]); //works with ver 10.5498 but not with 10.2.5
//add authorisation header
HttpClient.Request.CustomHeaders.Add('Authorization:Basic ' + ATHORISATION_STR); //byte64 encoding of the api key
HttpClient.ProtocolVersion := pv1_1; //get the full server response which allows for just one try-except
HttpClient.HTTPOptions := HttpClient.HTTPOptions + [hoKeepOrigProtocol, hoNoProtocolErrorException, hoWantProtocolErrorContent];
try
showmessage('about to post');
result := HttpClient.Post(THE_URL, FormData); //post to the api
showmessage('posted');
except
on E: Exception do
begin
result := E.ClassName + ': ' + E.message;
raise;
end;
end; //try
finally
FormData.Free;
IdSSLIOHandler.free;
HttpClient.free;
end;
I appreciate that this type of scenario is often caused by unintialised variables in the release version that would get automatically initialised when in the IDE / debug. But all the variables in my procedure do seem to be getting initialised before the call to POST.

How to get versions of files (exe's and dll's) which are included to Inno Setup installer exe file?

As in topic, is it possible? And, I want to display them on one page of installer if parameter (e.g. parameter passed to exe file) is set to true.
I know how to display some page:
if dev then
PageWersjePlikow :=
CreateOutputMsgMemoPage(
1, 'Wersje plików zawarte w instalatorze',
'Lista plików niewidoczna dla klienta',
'Pliki:', 'TU WPISAĆ WERSJE PLIKÓW');
I have some ideas, but every idea is based on .txt file built while compiling exe installer and then read from it...
Use GetVersionNumbers or GetVersionNumbersString support functions.
The GetVersionNumbersString returns version in format Major.Minor.Rev.Build.
If you need a different format, you need to use GetVersionNumbers and format the version components, the way you need (like Major.Minor.Rev):
function MyGetVersionNumbersString(
const Filename: String; var Version: String): Boolean;
var
MS, LS: Cardinal;
Major, Minor, Rev, Build: Cardinal;
begin
Result := GetVersionNumbers(Filename, MS, LS);
if Result then
begin
Major := MS shr 16;
Minor := MS and $FFFF;
Rev := LS shr 16;
Build := LS and $FFFF;
Version := Format('%d.%d.%d', [Major, Minor, Rev]);
end
end;
Thank you! I have found solution for checking cmd parameter:
function GetParam: Boolean;
var
param: string;
i: integer;
begin
Result := False;
for i:= 0 to ParamCount do
begin
param := ParamStr(i);
if (param = '-p') then
begin
Result := True;
break;
end;
end;
end;
With my function I can just run my installer with '-p' parameter and it will show my page containing information which I want :-)

Stored procedure Text saving in Delphi

I need to create stored procedure into oracle from delphi with TQuery.
But the SQL.text is difficult to uunderstand.
Is there any way to store direct text as pl/SQL with out quotes?
'create or replace '+
'function WholeTableRecovery(i_tablname IN varchar) return varchar '+
'as '+
Is it possible with resource file
Thanks in advance
Since you are using Delphi 2010 in the tags (I have no Delphi 7 here to test), a comfortable method would be storing the SQLs in separate textfiles, together with a RC file containing the directives for the resource compiler.
The RC files will contain the names of the resource you want to use together with the filenames containing the SQLs you want to store. The content for the example would look like this:
My_First_Speaking_ResourceName RCDATA "MyFirstSQL.sql"
My_Second_Speaking_ResourceName RCDATA "MySecondSQL.sql"
There is no need to call BRCC32 directly if you include the resource containing RC and resulting RES :
{$R 'MySQLResources.res' 'resources\MySQLResources.rc'}
You might wrap the usage of TResourceStream for your convenience, the way shown in the example would use Strings you might also work with the stream directly as mentioned by TLama MyQuery.SQL.LoadFromStream(rs);
implementation
{$R *.dfm}
{$R 'MySQLResources.res' 'resources\MySQLResources.rc'}
function LoadSqlResource(resourceName: string): string;
var
rs: TResourceStream;
sl: TStringList;
s : string;
begin
sl := TStringList.Create;
try
rs := TResourceStream.Create(hinstance, resourceName, RT_RCDATA);
try
rs.Position := 0;
sl.LoadFromStream(rs);
Result := sl.Text;
finally
rs.Free;
end;
finally
sl.Free;
end;
end;
procedure CallOneSql(Q:TADOQuery;ResourceName:String);
begin
Q.SQL.Text := LoadSqlResource('My_First_Speaking_ResourceName');
Q.ExecSQL;
end;
With a call like CallOneSql(MyQuery,'My_First_Speaking_ResourceName');
Make sure to create the project, not just compile if you made changes on the RC or the SQL files.

How to get File Created, Accessed and Modified dates the same as windows properties?

I am trying to get the same Created, Accessed and Modified dates as appears in the windows properties as in:
But am finding the times are consistently 30 minutes out:
Believe it may have something to do with timezones/daylight savings but have been unable to find a solution. Have tried looking at:
TimeZone Bias and adjusting and looking at different methods including:
How to get create/last modified dates of a file in Delphi?
Current code:
var
MyFd TWin32FindData;
FName: string;
MyTime: TFileTime;
MySysTime: TSystemTime;
myDate, CreateTime, AccessTime, ModTime: TDateTime;
Begin
...
FindFirstFile(PChar(FName), MyFd);
MyTime:=MyFd.ftCreationTime;
FileTimeToSystemTime(MyTime, MySysTime);
myDate := EncodeDateTime(MySysTime.wYear, MySysTime.wMonth, MySysTime.wDay, MySysTime.wHour,
MySysTime.wMinute, MySysTime.wSecond, MySysTime.wMilliseconds);
Memo1.Lines.Add('Created: '+ FormatDateTime('dddd, d mmmm yyyy, hh:mm:ss ampm', MyDate));
...
Any help appreciated
Thanks
Paul
I'm not sure what's wrong with your current code, but I believe this code will do what you need, using standard Windows API calls.
procedure TMyForm.ReportFileTimes(const FileName: string);
procedure ReportTime(const Name: string; const FileTime: TFileTime);
var
SystemTime, LocalTime: TSystemTime;
begin
if not FileTimeToSystemTime(FileTime, SystemTime) then
RaiseLastOSError;
if not SystemTimeToTzSpecificLocalTime(nil, SystemTime, LocalTime) then
RaiseLastOSError;
Memo1.Lines.Add(Name + ': ' + DateTimeToStr(SystemTimeToDateTime(LocalTime)));
end;
var
fad: TWin32FileAttributeData;
begin
if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, #fad) then
RaiseLastOSError;
Memo1.Clear;
Memo1.Lines.Add(FileName);
ReportTime('Created', fad.ftCreationTime);
ReportTime('Modified', fad.ftLastWriteTime);
ReportTime('Accessed', fad.ftLastAccessTime);
end;
procedure TMyForm.Button1Click(Sender: TObject);
begin
ReportFileTimes(Edit1.Text);
end;
You should be able to use the code below to transform a UTC date time value to a local date time vale:
uses
Windows;
function UTCTimeToLocalTime(const aValue: TDateTime): TDateTime;
var
lBias: Integer;
lTZI: TTimeZoneInformation;
begin
lBias := 0;
case GetTimeZoneInformation(lTZI) of
TIME_ZONE_ID_UNKNOWN:
lBias := lTZI.Bias;
TIME_ZONE_ID_DAYLIGHT:
lBias := lTZI.Bias + lTZI.DaylightBias;
TIME_ZONE_ID_STANDARD:
lBias := lTZI.Bias + lTZI.StandardBias;
end;
// UTC = local time + bias
// bias is in number of minutes, TDateTime is in days
Result := aValue - (lBias / (24 * 60));
end;
Judging from your images your offset is actually 10 hours and 30 minutes. Are you located in South Australia?

Resources