Is there some way to find the name of a shortcut (present on desktop) through the associated program name?
Ex:
Filename:
C:\Program Files\Mozilla Firefox\firefox.exe
and result in:
C:\Users\Public\Desktop\Firefox.lnk
I found something near to this, but is made the opposite way (returns the associated program name by shortcut name).
The application knows nothing about shortcuts that are created to point to it, so this isn't possible. You'd have to iterate every file in the user's Desktop folder looking for shortcut files, open them using IShellLink, and look to see if they launched the application you're looking to find. Here's an example of doing so. You'll need to add ShellAPI to your uses clause. FileName is the fully qualified name of the shortcut file.
function GetLinkPath(const FileName: WideString): String;
var
ShellLink: IShellLink;
Path: array[0..MAX_PATH] of Char;
begin
Result := '';
ShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
if (ShellLink as IPersistFile).Load(PWideChar(FileName), STGM_READ) = 0 then
begin
if ShellLink.GetPath(Path, MAX_PATH, nil, SLGP_SHORTPATH) = 0 then
Result := Path;
end;
end;
Related
The code below shows: "Unable to create file "test.txt". Access is denied."
var F: TFileStream;
begin
F := TFileStream.Create('test.txt', fmCreate);
F.free;
end;
Am I doing something wrong? Folder is not protected in any way and all other programs can write files there. Lazarus 2.2.0 on Windows 7.
It doesn't guaranteed create the file in the same dir as the EXE. It creates the file in the working dir of the application, which is not necessarily the EXE dir, which varies depending on how you execute the EXE.
Try
var sExePath : string;
..
sExePath := includetrailingpathdelimiter(ExtractFilePath(paramstr(0)));
F := TFileStream.Create(sExePath+'test.txt', fmCreate);
Note this is similar to Delphi
I see the pascal code below on another forum. How can this code be possible?
Doesn't windows allow user to create a filename with colon?
However, this code only work when you create a file with name contains colon in root directory of drive (Ex: D:, C:, E:, etc). And when the file is created, it's completely invisible.
uses crt, sysutils;
var
f, f1: file of char;
c:char;
begin
clrscr;
assign(f, 'D:\src\payload.exe');
reset(f);
assign(f1, 'D:\:malware.exe');
rewrite(f1);
while not eof(f) do
begin
read(f, c);
write(f1, c);
end;
close(f1);
close(f);
executeprocess('D:\:malware.exe', ''); //here
readln;
erase(f1);
end.
You can compile the code above with free pascal
fpc [filename].pas
Thank you.
EDIT:
For more detail:
You can execute D:\:malware.exe from CreateProcess (WinAPI)
You can't execute D:\:malware.exe from command line, path, etc
I use process explorer to find D:\:malware.exe path/contain folder. However, when I pressed explore button, it takes me to %UserProfile%
It only work for D:\:malware.exe, D:\\malware.exe, D:\/malware.exe
It works because it is possible*. You can name files all kinds of horrid things, regardless of proper naming convention.
*Yes, I know MSDN lists colons as “reserved”. That is not the same as forbidden or impossible. It is only the same as “don’t do it”.
I need to insert the last part of the installation dirrectory in the icon name.
To do that I'm trying to use ExtractFileName({app}), and insert its result in the Name parameter of my icon.
[Icons]
Name: '{group}\ApplicationName\' + ExtractFileName({app}) + '\filename.txt'
It compiles, but at runtime I get a 123 error, telling that
c:\Windows\system32\'c: could not be created.
I just need to insert the basename of the installation path as a new level in start menu.
You are looking for a scripted constant.
[Icons]
Name: "{group}\ApplicationName\{code:GetAppName}\filename.txt"
[Code]
function GetAppName(Param: string): string;
begin
Result := ExtractFileName(ExpandConstant('{app}'));
end;
I have a path to a directory saved as a string, and wanted to know how I can easily and robustly extract the parent directory from this string?
I tried to see if there is some method for this in FileUtil and SysUtils, but haven't found anything so far.
The simplest way is to find the last path delimiter character and trim the source string. BTW there are some alternative:
program Project1;
uses
sysutils;
var
sExe: string;
sParent: string;
sParentProper: string;
begin
sExe := ExtractFilePath(ParamStr(0)); // Get executable directory
Writeln(sExe);
sParent := IncludeTrailingPathDelimiter(sExe) + '..' + PathDelim; // Make parent path for executable
Writeln(sParent);
sParentProper := ExpandFileName(sParent); // Get absolute path based on relative path
WriteLn(sParentProper);
Readln;
end.
And output is:
C:\Users\nd\AppData\Local\Temp\
C:\Users\nd\AppData\Local\Temp\..\
C:\Users\nd\AppData\Local\
So using this technique the proper way is ExpandFileName(IncludeTrailingPathDelimiter(sBasePath) + '..')
PS: We are using only sysutils unit so it is pure FPC solution and it is not require any LCL libraries.
An even simpler way to do this would be:
parentDirPath := ExtractFilePath(ExcludeTrailingPathDelimiter(thePath));
This works on the three major platforms (Linux, Mac OS X and Windows), and thePath may refer to a file or a folder.
Well, I of course figured it out only after asking about it here:
parentDirPath := FileUtil.ExtractFileNameOnly(
FileUtil.ChompPathDelim(theSubDirPath));
... will do!
The FileUtil.ChompPathDelim() part is necessary to "fool" FPC to believe the top folder is a "file" (so no trailing slash allowed).
I'm trying to open file changelog.txt and I need to open it no matter what user is opening it. It's however always located in ~/ directory. Access the file. Here's my code:
procedure TForm1.FormCreate(Sender: TObject);
var myFile : TextFile;
line : string;
begin
AssignFile(myFile, '~/changelog.txt');
Reset(myFile);
while not Eof(myFile) do
begin
ReadLn(myFile, line);
Label3.Caption := (Label3.Caption + line + #13#10);
end;
CloseFile(myFile);
end;
It doesn't work. However, if I replace ~ with the actual username, it works. However, I cannot know the username of each user that will run my program. Any ideas how can I get the username of user that started the program? Thanks!
Edit1: I have tried this, but it also includes a new line:
RunCommand('/bin/bash',['-c','whoami'],user);
This is normal. "~" is a shell level concept and thus needs a separate shell invocation to evaluate. Assignfile calls the kernel interfaces directly though and thus doesn't understand this.
Use getenvironmentvariable('HOME') to get the homedir from the environment. Better even, getuserdir allows to get the home dir in a crossplatform manner.