Introduction
Here in this tip, I'll show you adding into your Windows Explorer's context menu an option for copying the file address. Although most of us don't have any issue with manually copying the file address, but sometimes it is painful when the file name is more complex or you have to do this frequently.
Background
I remember the time when I had to put the file names (fully qualified) on command prompt. It took a long time and extra effort. It prompted me to design a very simple application that could have simply copied the address. I initially designed it in C# but would like to put forward the C version. However I would be posting both the codes( :) for C# fans).
Steps
We have got only a couple steps to achieve our objective.
- Setting the registry:
To add to Windows explorer's context menu any option, it is required to add a key at HKEY_CLASSES_ROOT\*\shell. This will make the menu available for any file type. Thus our keys will be:
HKEY_CLASSES_ROOT\*\shell\Copy Address and the command associated with it becomes: HKEY_CLASSES_ROOT\*\shell\Copy Address\command.
Under the command key, only thing that needs to be set is data value, i.e., C:\Windows\CopyAddress.exe %1.
Besides data, the name and type values will remain (Default)
and REG_SZ
respectively.
- Writing the code:
It was simple till here and it's the last step, let's finish it off. As we can see in the registry value shown above " CopyAddress.exe %1
", the %1
parameter will push the file address into the programs argument. We need to capture that address onto the clipboard for further usage. I'll show it in the next section how to write the handling code.
Using the Code
The code is not so big and just includes 4 to 5 WinAPI calls. And I'll better show the code first:
#include <stdio.h>
#include <Windows.h>
#pragma comment(linker,"/SUBSYSTEM:WINDOWS")
int _stdcall WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
LPTSTR lptstrCopy;
HANDLE hglbCopy;
if (!OpenClipboard(NULL))
return MessageBoxA(0,"Operation Failed \r\n
Can't Open Clipboard ","Copy Error",MB_ICONERROR);
EmptyClipboard();
hglbCopy= GlobalAlloc(GMEM_ZEROINIT |
GMEM_MOVEABLE,(lstrlen(lpCmdLine)+1)*sizeof(CHAR));
if (hglbCopy == NULL)
{
CloseClipboard();
return MessageBoxA(0,"Operation Failed \r\n
Unable to Allocate Memory ","Copy Error",MB_ICONERROR);
}
lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
lstrcpyA(lptstrCopy,lpCmdLine);
lptstrCopy[lstrlen(lpCmdLine)-1]=0; GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT, hglbCopy);
CloseClipboard();
return 0;
}
int main(int argc,char* argv[])
{
LPTSTR lptstrCopy;
HANDLE hglbCopy;
int i=1;
if (!OpenClipboard(NULL))
return MessageBoxA(0,"Operation Failed ",
"Copy Error",MB_ICONERROR);
EmptyClipboard();
hglbCopy= GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE,256*sizeof(char));
if (hglbCopy == NULL)
{
CloseClipboard();
return MessageBoxA(0,"Operation Failed ",
"Copy Error",MB_ICONERROR);
}
lptstrCopy = (LPTSTR)GlobalLock(hglbCopy);
while(i<argc)
{
strcat(lptstrCopy,argv[i++]);
if((i<argc)){strcat(lptstrCopy," ");}
}
GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT, hglbCopy);
CloseClipboard();
return 0;
}
I have given two codes one for CONSOLE SUBSYSTEM another for WINDOWS SUBSYSTEM. Explanation of the code:
To copy any data to clipboard, OpenClipboard
must have been called. To delete the previous data, EmptyClipboard
is required. To get a handle to the memory object, we will use GlobalAlloc
and to use it in a pointer, GlobalLock
is called. After that, nothing is a big deal, just copy into the string
the command line parameter and set it to the clipboard using SetClipboardData
function. CF_TEXT
is the flag for text data.
The equivalent code in C# is shown below:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace Copy
{
class Program
{ [STAThread]
static void Main(string[] args)
{
try
{
string Address = "";
foreach (string ar in args)
{
Address += ar+" ";
}
Clipboard.SetText(Address);
}
catch { }
Application.Exit();
}
}
}
I don't find things need to be explained in C#. ;) .They are self explaining, the only suggestion I'll give is to link it as Windows Application rather than Console Application and you'll avoid the pop ups.
Points of Interest
The most disappointing thing while coding with console was the array formation in the command line parameter because of the split character space. It ate an extra 30 min!! I'll be uploading the code files using this app!!!!!!!! ;)