Delphi Tinifile.ReadString and PromptDataSource - delphi

The first, click button1,can get the [section].[Key].Value
but if change the path via the second page's [...] of PromptDataSource()
Then the next time, click button1, can not get the [section].[Key].Value
Why???
Awe.dat
[Options]
DBConnection=Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\2000.mdb;
the Button1Click's code
procedure TForm1.Button1Click(Sender: TObject);
var
Filename:string;
DatFile:TiniFile;
str:WideString;
ConnectStr:WideString;
begin
DatFile:=Tinifile.Create('.\Awe.dat');
str:=DatFile.ReadString('Options','DBConnection','');
ShowMessage(str+'-----------------');
ConnectStr:=PromptDataSource(handle,str);
ShowMessage(str+'-----------------'+ConnectStr);
DatFile.Free;
end;

It seems that the problem is related to your use of a relative path. Your path is relative to the process working directory.
If the working directory is in your complete control then your code would be fine. But often the working directory is not in your complete control. The process may start with an unexpected working directory. File dialogs may change the working directory.
You are better being explicit and providing a full path to the file. It looks like your file is in the same directory as the executable. So you could use:
ExtractFilePath(Application.ExeName) + FileName
or similar.

Related

In Delphi XE7 when running a program in the IDE cannot create a log file, but it works when I run the created exe

When I start a program in the IDE, I use the following code to generate a log file. All of the paths are correct, checked with F8, but the log file is not output.
When I run the executable outside of the IDE, the log file is output properly.
Is there a setting somewhere in XE7 that prohibits this?
procedure LogProgram(const aEvent: String);
var
TheLogFileName, TheLogLine: String;
TheLogFile: TextFile;
TheDay, TheMonth, TheYear, TheHour, TheMinute, TheSecond,
TheMilliSecond: Word;
begin
TheLogFileName := Format('%s%d.log', [usPATH_LOGS, Trunc(Now)]);
AssignFile(TheLogFile, TheLogFileName);
if not FileExists(TheLogFileName) then
Rewrite(TheLogFile);
Append(TheLogFile);
DecodeDateTime(Now, TheYear, TheMonth, TheDay, TheHour, TheMinute, TheSecond,
TheMilliSecond);
TheLogLine := Format('%d-%d-%d: %d:%d:%d:%d%s%s', [TheYear, TheMonth, TheDay,
TheHour, TheMinute, TheSecond, TheMilliSecond, #9, aEvent]);
Writeln(TheLogFile, TheLogLine);
CloseFile(TheLogFile);
end;
I tried to output a file, using the above code, while a program was running in the Delphi XE7 IDE, expected a log (text) file and got no output. Running the same program outside of the IDE generates the log (text) file properly.
#fpiette I checked Windows Security and folder protection is not active.
#Andreas-Rejbrand I'm using relative paths. Paths are being calculated relative to the path of the executable
#SilverWarior I did not change anything in Delphi through menu Run->Parameters. There are no paths listed there.
I did a global search (on my computer) for the name of the file, I was trying to create and discovered it in a containment folder (c:\VTRoot) managed by Comodo antivirus.
It turned out that if Comodo thought the file being created was a security risk, it moved it to the containment area on C:\
I went to the Comodo dashboard and disabled Auto-Containment and now Delphi XE7 works as it should.

TEdgeBrowser not working under folder path with spaces

I've been stuck with this weird TEdgeBrowser behavior for the past couple of days. I'd appreciate if someone could shed some light here...
I created a sample project with just the below info. It works fine and loads index.html into the EdgeBrowser component - all is good:
procedure TForm2.Button1Click(Sender: TObject);
begin
EdgeBrowser1.UserDataFolder := 'C:\temp';
EdgeBrowser1.Navigate('file:///C:\Users\jimsweb\Desktop\index.html');
end;
Things get interesting when I move the resulting executable to a folder such as "New Folder" (note that there is a space in between "New" and "Folder"). Now, run the exe from New Folder, and the index.html file won't load!! Move the executable back to a path that doesn't have spaces in it, and again the EdgeBrowser component will behave normally and load index.html.
I suspect that the component cannot handle paths with spaces.
How can I prevent this behavior?

File Not Found in Delphi (FMX)

I am trying to load a bunch of lines from a text file located in same directory as the .dproj and Delphi can't find the file I'm trying to read from.
the code is as follows:
procedure TFoPrincipale.Button2Click(Sender: TObject);
var monFich : TextFile;
Sligne : string;
begin
try
AssignFile(monFich, 'docText.txt');
Reset(monFich);
except
showmessage('Le fichier est introuvable');
exit;
end;
while not Eof (monFich) do
begin
Readln(monFich, Sligne);
Memo1.Lines.Add(Sligne);
end;
CloseFile(monFich);
end;
If you are using default project options then your application executable isn't compiled into the project directory but instead into the Win32\Debug or Win32\Release subfolder of your project folder.
So you should take into account the relative path to your file. In your case, the desired file is in second parent folder of the folder in which your executable resides.
I recommend you first get the path location of your executable file using ExtractFilePath(Application.ExeName).
Then you can make use of TDirectory.GetParent() in order to move up the directory chain until you reach the desired directory.

Application cant access file on startup

I'm doing an application(XE6 , Firemonkey) to synchronize files between a shared folder and a computer/s. This application checks every x hours if there are new files to be synchronized, and it starts on windows start-up.
I can do everything, my application starts on start-up, and it does the synchronization, as long as i'm the one starting it. Whem the application auto starts on start up it gives me an exception "EINOUTERROR" - File Access Denied.
On starting the application reads a small .txt file to set up it self (shared folder location, rate of synchronization etc), my guess is that since its the windows starting the app runs it without privileges to read the .txt, but even after changing the .txt permissions to full control on everyone it gives the same error.
File open code:
AssignFile(myFile,'Dados.txt');
if FileExists('Dados.txt') then
Append(myFile)
else
Rewrite(myFile);
FileMode := fmOpenRead;
Reset(myFile);
Code of placing the app on startup programs :
procedure TSyncM.RunOnStartup(const sCmdLine: string; bRunOnce: boolean; Remove: Boolean) ;
var sKey: string;
Section: string;
const ApplicationTitle = 'GEN4Sync';
begin
if (bRunOnce) then
sKey := 'Once'
else
sKey := '';
Section := 'Software\Microsoft\Windows\CurrentVersion\Run' + sKey + #0;
with TRegIniFile.Create('') do
try
RootKey := HKEY_CURRENT_USER;
if Remove then
DeleteKey(Section, ApplicationTitle)
else
WriteString(Section, ApplicationTitle, sCmdLine) ;
finally
Free;
end;
end;
If i comment the piece of code that calls the reading of that .txt my app starts and executes well, but i don't want to set it up everytime.
Thanks in advance
I think that the issue is related to your use of relative paths. You have written the code under the assumption that the working directory is the same directory as contains the executable. That is not necessarily so.
When you start the application by double clicking on the executable file, for instance, the shell ensures that the initial working directory is the directory containing the executable file. However, when Windows starts your program at startup I suspect that the working directory is the system directory. And of course your file is not found there, and you don't have rights to write there.
Instead of using relative paths, use the full path to the file.
FileName := ExtractFilePath(ParamStr(0)) + 'Dados.txt';
Or perhaps
FileName := TPath.Combine(ExtractFilePath(ParamStr(0)), 'Dados.txt');
Note that this does also assume that your executable file is located in a folder which you can write to. That is often not the case so you may need to find a different location.
I do have to comment that I find it somewhat incongruous that you are mixing the very modern (FireMonkey) with the ancient (Pascal I/O). Perhaps it is time to move to a more modern I/O technique.

Get/Set TShellListView Path/Folder as String (Not Using .Root)

I want to set the path for a TShellListView to display a directory of files using Delphi 2007. I can initially use TShellListView.Root to set the root path like this and it shows the directory I want:
View := TShellListView.Create(Self);
// ...
View.Root := 'C:\Windows';
But if the user navigates away from that directory using backspace and I try to set the .Root back to the original directory, the directory displayed does not change. It looks like .Root is meant to define the root of the shell namespace, not the current directory.
Also, if the user navigates around (using backspace, etc.) the .Root property does not update to reflect the currently displayed path. There is no .Path property like there is for TShellTreeView.
What I want is a way to get and set the current path as a string without being required to link the TShellListView to a TShellTreeView and set TShellTreeView.Path or hack ShellCtrls.pas since the relevant methods of TShellListView all look private. I find it hard to believe there isn't a straightforward way to get/set the path, so I assume I'm missing something simple here, but this component is not documented at all.
You can get the currently loaded path using
ShellListView1.RootFolder.PathName
Setting the Root property works, but it isn't updated when you change folders interactively. So you need to force it to think there's a change. This works if you're always resetting it to the same original path:
ShellListView1.Root := View.RootFolder.PathName; // Updates to current location
ShellListView1.Root := 'C:\Windows';
Alternatively, for arbitrary paths you could just add/remove the trailing \ in order to fool the SameText check in SetRoot:
if ShellListView1.Root[Length(ShellListView1.Root)] = '\' then
ShellListView1.Root := ExcludeTrailingPathDelimiter(ANewPath)
else
ShellListView1.Root := IncludeTrailingPathDelimiter(ANewPath);
To get the current folder as a string, you can access the RootFolder-property.
procedure TForm2.Button1Click(Sender: TObject);
begin
showmessage(ShellListView1.RootFolder.PathName);
end;
To set the current folder as a string, you use the root-property.
procedure TForm2.Button2Click(Sender: TObject);
begin
ShellListView1.Root := 'C:\windows';
end;

Resources