Mail Archives: cygwin/2002/03/02/11:09:09
--Boundary_(ID_dPakcDH3/esVabVNGHA6sA)
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT
Content-disposition: inline
Joshua,
On Fri, Mar 01, 2002 at 05:00:36PM -0800, Joshua Daniel Franklin wrote:
> Has anyone even seen something like this before?
No, but see attached for my version of mkshortcut -- mksc. Note that
mksc.cpp needs to be compiled with MS cl.exe, but hopefully perusing the
code will help you debug your problem.
Jason
--Boundary_(ID_dPakcDH3/esVabVNGHA6sA)
Content-type: text/plain; charset=us-ascii; NAME=mksc.cpp
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=mksc.cpp
/*
* Copyright (c) 2000, 2002, Jason Tishler.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* A copy of the GNU General Public License can be found at
* http://www.gnu.org/
*
* Written by Jason Tishler <jason AT tishler DOT net>
*
* $Id: mksc.cpp,v 1.3 2002/03/02 16:12:11 jt Exp $
*/
#include <windows.h>
#include <iostream>
#include <string>
#include <shlguid.h>
#include <shlobj.h>
using namespace std;
DWORD MakeShortcut(
const string& aPath,
const string& anArguments,
const string& aWorkingDirectory,
const string& anIconLocation,
int anIconIndex,
const string& aShortcutPath);
void ParseArgs(
int argc,
char* argv[],
string& aPath,
string& anArguments,
string& aWorkingDirectory,
string& anIconLocation,
int& anIconIndex,
string& aShortcutPath);
void PrintUsage();
string CollapseBackslashes(const char* aString);
int
main(int argc, char* argv[])
{
string aPath;
string anArguments;
string aWorkingDirectory;
string anIconLocation;
int anIconIndex = 0;
string aShortcutPath;
// Parse command line arguments
ParseArgs(
argc,
argv,
aPath,
anArguments,
aWorkingDirectory,
anIconLocation,
anIconIndex,
aShortcutPath);
// Create shortcut
DWORD aStatus = MakeShortcut(
aPath,
anArguments,
aWorkingDirectory,
anIconLocation,
anIconIndex,
aShortcutPath);
if (aStatus != ERROR_SUCCESS)
{
cerr << "MakeShortcut failed with error = " << aStatus << endl;
}
return (aStatus == ERROR_SUCCESS) ? 0 : 2;
}
DWORD
MakeShortcut(
const string& aPath,
const string& anArguments,
const string& aWorkingDirectory,
const string& anIconLocation,
int anIconIndex,
const string& aShortcutPath)
{
// Variable definitions located here due to use of gotos
IShellLink *aShellLink = 0;
IPersistFile* aPersistFile = 0;
int aStatus2 = 0;
DWORD aReturnCode = ERROR_SUCCESS;
// Initialize COM
HRESULT aStatus = CoInitialize(0);
if (FAILED(aStatus))
{
aReturnCode = GetLastError();
cerr << "CoInitialize failed with error = " << aReturnCode << endl;
goto exit;
}
// Create shell link instance
aStatus = CoCreateInstance(
CLSID_ShellLink,
0,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void **) &aShellLink);
if (FAILED(aStatus))
{
aReturnCode = GetLastError();
cerr << "CoCreateInstance failed with error = " << aReturnCode << endl;
goto exit;
}
// Set the shell link's command path
aStatus = aShellLink->SetPath(aPath.c_str());
if (FAILED(aStatus))
{
aReturnCode = aStatus;
cerr << "IShellLink::SetPath failed with HRESULT = " << aStatus << endl;
goto exit;
}
// Set the shell link's command arguments
aStatus = aShellLink->SetArguments(anArguments.c_str());
if (FAILED(aStatus))
{
aReturnCode = aStatus;
cerr << "IShellLink::SetArguments failed with HRESULT = " << aStatus << endl;
goto exit;
}
// Set the shell link's working directory, if necessary
if (aWorkingDirectory.size() > 0)
{
aStatus = aShellLink->SetWorkingDirectory(aWorkingDirectory.c_str());
if (FAILED(aStatus))
{
aReturnCode = aStatus;
cerr << "IShellLink::SetWorkingDirectory failed with HRESULT = " << aStatus << endl;
goto exit;
}
}
// Set the shell link's icon, if necessary
if (anIconLocation.size() > 0)
{
aStatus = aShellLink->SetIconLocation(anIconLocation.c_str(), anIconIndex);
if (FAILED(aStatus))
{
aReturnCode = aStatus;
cerr << "IShellLink::SetIconLocation failed with HRESULT = " << aStatus << endl;
goto exit;
}
}
// Get the shell link's persist file interface
aStatus = aShellLink->QueryInterface(
IID_IPersistFile,
(void **) &aPersistFile);
if (FAILED(aStatus))
{
aReturnCode = GetLastError();
cerr << "IShellLink::QueryInterface failed with error = " << aReturnCode << endl;
goto exit;
}
// Convert the shortcut path to Unicode
WCHAR aWideShortcutPath[MAX_PATH];
aStatus2 = MultiByteToWideChar(
CP_ACP,
0,
aShortcutPath.c_str(),
-1,
aWideShortcutPath,
MAX_PATH);
if (aStatus2 == 0)
{
aReturnCode = GetLastError();
cerr << "MultiByteToWideChar failed with error = " << aReturnCode << endl;
goto exit;
}
// Save the shell link to the filesytem
aStatus = aPersistFile->Save(aWideShortcutPath, TRUE);
if (FAILED(aStatus))
{
aReturnCode = GetLastError();
cerr << "IPersistFile::Save failed with error = " << aReturnCode << endl;
goto exit;
}
exit:
// Clean up
if (aPersistFile)
aPersistFile->Release();
if (aShellLink)
aShellLink->Release();
CoUninitialize();
return aReturnCode;
}
void
ParseArgs(
int argc,
char* argv[],
string& aPath,
string& anArguments,
string& aWorkingDirectory,
string& anIconLocation,
int& anIconIndex,
string& aShortcutPath)
{
// Print usage, if appropriate
if (argc == 1)
{
PrintUsage();
exit(1);
}
// Process arguments
for (int i = 1; i < argc; i += 2)
{
if (i + 1 >= argc)
{
PrintUsage();
exit(1);
}
if (strcmp(argv[i], "--cmd") == 0)
{
aPath = CollapseBackslashes(argv[i + 1]);
}
else if (strcmp(argv[i], "--args") == 0)
{
anArguments = CollapseBackslashes(argv[i + 1]);
}
else if (strcmp(argv[i], "--dir") == 0)
{
aWorkingDirectory = CollapseBackslashes(argv[i + 1]);
}
else if (strcmp(argv[i], "--icon") == 0)
{
anIconLocation = CollapseBackslashes(argv[i + 1]);
}
else if (strcmp(argv[i], "--index") == 0)
{
anIconIndex = atoi(argv[i + 1]);
}
else if (strcmp(argv[i], "--shortcut") == 0)
{
aShortcutPath = CollapseBackslashes(argv[i + 1]);
}
else
{
PrintUsage();
exit(1);
}
}
// Check for mandatory arguments
if (aPath.size() == 0 || anArguments.size() == 0 || aShortcutPath.size() == 0)
{
PrintUsage();
exit(1);
}
}
void
PrintUsage()
{
cerr << "usage: mksc --cmd CommandPath --args CommandArguments" << endl;
cerr << " --shortcut ShortcutPath [--dir WorkingDirectory]" << endl;
cerr << " [--icon IconPath] [--index IconIndex]" << endl;
}
string
CollapseBackslashes(const char* aString)
{
const string theDoubleBackslashRe = "\\\\";
const string theSpaceRe = " ";
string aFixedString = aString;
// Determine if string does not contains any spaces, if so just return
if (string::size_type i = aFixedString.find(theSpaceRe) == string::npos)
return aFixedString;
// Collapse double backslashes into single
for (string::size_type i = aFixedString.find(theDoubleBackslashRe);
i != string::npos;
i = aFixedString.find(theDoubleBackslashRe, i))
{
i++;
aFixedString.erase(i, 1);
}
return aFixedString;
}
--Boundary_(ID_dPakcDH3/esVabVNGHA6sA)
Content-Type: text/plain; charset=us-ascii
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
--Boundary_(ID_dPakcDH3/esVabVNGHA6sA)--
- Raw text -