Create Windows "shortcut" (.lnk) with D?
岩倉 澪 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Mar 5 19:13:23 PST 2016
I'm creating a small installation script in D, but I've been
having trouble getting shortcut creation to work! I'm a linux
guy, so I don't know much about Windows programming...
Here are the relevant bits of code I have:
import core.sys.windows.basetyps, core.sys.windows.com,
core.sys.windows.objbase, core.sys.windows.objidl,
core.sys.windows.shlobj, core.sys.windows.windef;
import std.conv, std.exception, std.file, std.format, std.path,
std.stdio, std.string, std.utf, std.zip;
//Couldn't find these in core.sys.windows
extern(C) const GUID CLSID_ShellLink = {0x00021401, 0x0000,
0x0000,
[0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
extern(C) const IID IID_IShellLinkA = {0x000214EE, 0x0000,
0x0000,
[0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
extern(C) const IID IID_IPersistFile = {0x0000010B, 0x0000,
0x0000,
[0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46]};
void main()
{
string programFolder, dataFolder, desktopFolder;
{
char[MAX_PATH] _programFolder, _dataFolder,
_desktopFolder;
SHGetFolderPathA(null, CSIDL_PROGRAM_FILESX86, null, 0,
_programFolder.ptr);
SHGetFolderPathA(null, CSIDL_LOCAL_APPDATA, null, 0,
_dataFolder.ptr);
SHGetFolderPathA(null, CSIDL_DESKTOPDIRECTORY, null, 0,
_desktopFolder.ptr);
programFolder =
_programFolder.assumeUnique().ptr.fromStringz();
dataFolder = _dataFolder.assumeUnique().ptr.fromStringz();
desktopFolder =
_desktopFolder.assumeUnique().ptr.fromStringz();
}
auto inputFolder = buildNormalizedPath(dataFolder,
"Aker/agtoolbox/input");
auto outputFolder = buildNormalizedPath(dataFolder,
"Aker/agtoolbox/output");
CoInitialize(null);
scope(exit)
CoUninitialize();
IShellLinkA* shellLink;
IPersistFile* linkFile;
CoCreateInstance(&CLSID_ShellLink, null,
CLSCTX_INPROC_SERVER, &IID_IShellLinkA, cast(void**)&shellLink);
auto exePath = buildNormalizedPath(programFolder,
"Aker/agtoolbox/agtoolbox.exe").toStringz();
shellLink.SetPath(exePath);
auto arguments = format("-i %s -o %s", inputFolder,
outputFolder).toStringz();
shellLink.SetArguments(arguments);
auto workingDirectory = programFolder.toStringz();
shellLink.SetWorkingDirectory(workingDirectory);
shellLink.QueryInterface(&IID_IPersistFile,
cast(void**)&linkFile);
auto linkPath = buildNormalizedPath(desktopFolder,
"agtoolbox.lnk").toUTF16z();
linkFile.Save(linkPath, TRUE);
}
I tried sprinkling it with print statements and it crashes on
shellLink.setPath(exePath);
This is the full script:
https://gist.github.com/miotatsu/1cc55fe29d8a8dcccab5
I found the values for the missing windows api bits from this:
http://www.dsource.org/projects/tutorials/wiki/CreateLinkUsingCom
I compile with: dmd agtoolbox-installer.d ole32.lib
I got the ole32.lib from the dmd install
Any help would be highly appreciated as I'm new to Windows
programming in D and have no idea what I'm doing wrong!
More information about the Digitalmars-d-learn
mailing list