我是这样在windows右键菜单上添加菜单项的。
在其他平台上都是好的,唯独在Win7 X64上和Windows自己的菜单冲突。
当运行“Run as administrator”时,会运行我的程序。
为什么会这样?谢谢
// EShellExt.cpp : Implementation of CEShellExt#include "stdafx.h"
#include "EShellExt.h"
// CEShellExt
CStringArray CEShellExt::m_stringArrayFileNames;BOOL CEShellExt::RegisterSysOpenFile(CStringArray & m_stringArrayFileNames)
{
m_szSysDirectory[0] = 0X00;
if(!SHGetSpecialFolderPath(NULL, m_szSysDirectory, CSIDL_APPDATA, FALSE))
{
int nErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage( 
FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_SYSTEM | 
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL 
);
// Display the string.
MessageBox(NULL, (LPCTSTR)lpMsgBuf, _T("Error"), MB_ICONERROR | MB_OK); }
wcscat_s(m_szSysDirectory, CL_MAX_PATH_LEN, _T("\\PilotEdit")); CFile fileOpenList;
BOOL bFileOpenSucc = FALSE;
while(!bFileOpenSucc)
{
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
_snwprintf_s(m_wszTempBuffer, LENGTH_MAX_BUFF, LENGTH_MAX_BUFF, _T("%s\\O_P_%u"), m_szSysDirectory, ((systemTime.wHour * 60 + systemTime.wMinute) * 60 + systemTime.wSecond) * 1000 + systemTime.wMilliseconds);
if(fileOpenList.Open(m_wszTempBuffer, CFile::modeReadWrite | CFile::modeCreate | CFile::modeNoTruncate | CFile::shareExclusive | CFile::shareDenyWrite))
{
bFileOpenSucc = TRUE;
}
else
{
Sleep(100);
}
} fileOpenList.SeekToEnd();
for(int i = 0; i < m_stringArrayFileNames.GetCount(); i++)
{
_snwprintf_s(m_wszTempBuffer, LENGTH_MAX_BUFF, LENGTH_MAX_BUFF, _T("%s"), m_stringArrayFileNames.GetAt(i));
fileOpenList.Write(m_wszTempBuffer, (unsigned int)wcslen(m_wszTempBuffer) * 2);
fileOpenList.Write(_T("?"), 2);
}
fileOpenList.Close(); return TRUE;
}HRESULT CEShellExt::Initialize ( LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID )
{
m_hRegBmp = LoadBitmap(_AtlBaseModule.GetModuleInstance(), MAKEINTRESOURCE(IDB_PILOTEDITBMP)); FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;
TCHAR szFile [CL_MAX_PATH_LEN];
int nNumFiles;
m_stringArrayFileNames.RemoveAll();
// 在数据对象内查找 CF_HDROP 型数据.
if ( FAILED( pDataObj->GetData ( &fmt, &stg )))
{
// Nope! Return an "invalid argument" error back to Explorer.
return E_INVALIDARG;
} // 获得指向实际数据的指针
hDrop = (HDROP) GlobalLock ( stg.hGlobal ); // 检查非NULL.
if ( NULL == hDrop )
{
return E_INVALIDARG;
} // 检查在该操作中有几个文件被选择.
nNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 ); if(0 == nNumFiles)
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
} /* // 有效性检查 – 保证最少有一个文件名.
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );
if ( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
} */ for ( int uFile = 0; uFile < nNumFiles; uFile++ )
{
//取得下一个文件名.
if ( 0 == DragQueryFile ( hDrop,
uFile, szFile, MAX_PATH ))
continue; m_stringArrayFileNames.Add(szFile);
} // end for GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return ( m_stringArrayFileNames.GetCount() > 0 ) ? S_OK : E_INVALIDARG;
}HRESULT CEShellExt::QueryContextMenu ( HMENU hmenu,UINT uMenuIndex, UINT uidFirstCmd, UINT uidLastCmd, UINT uFlags )
{         
UINT uCmdID = uidFirstCmd;
// 如果标志包含 CMF_DEFAULTONLY 我们不作任何事情.
if ( uFlags & CMF_DEFAULTONLY )
{
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );
} InsertMenu(hmenu, uMenuIndex, MF_STRING  | MF_BYPOSITION, uCmdID++, _T("PilotEdit"));
SetMenuItemBitmaps(hmenu, uMenuIndex, MF_BYPOSITION, m_hRegBmp, m_hRegBmp);
//最后告诉浏览器我们添加了几个菜单项
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 1);
}HRESULT CEShellExt::GetCommandString( UINT idCmd, UINT uFlags,UINT* pwReserved, LPSTR pszName, UINT cchMax )
{
USES_CONVERSION;
// 如果 Explorer 要求帮助字符串,就将它拷贝到提供的缓冲区中.
if ( uFlags & GCS_HELPTEXT )
{
lstrcpynW ( (LPWSTR) pszName, _T("PilotEdit"), cchMax );
return S_OK;
} return E_INVALIDARG;
}HRESULT CEShellExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )

if(m_stringArrayFileNames.GetCount() > 0)
{
RegisterSysOpenFile(m_stringArrayFileNames); int nPathLen = GetModuleFileName(_AtlBaseModule.GetModuleInstance(), m_wszTempBuffer + 1, CL_MAX_PATH_LEN);
m_wszTempBuffer[0] = _T('\"');
for(int i = nPathLen - 1; i>= 0; i--)
{
if(m_wszTempBuffer[i] != _T('\\') && m_wszTempBuffer[i] != _T('/'))
{
m_wszTempBuffer[i] = 0X00;
}
else
{
wcscat_s(m_wszTempBuffer, LENGTH_MAX_BUFF, _T("PilotEdit.exe\" DUMMY"));
break;
}
}
//MessageBox(NULL,m_wszTempBuffer, _T("PilotEdit"), MB_OK); 

STARTUPINFO si;
PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if( !CreateProcess( NULL,   // No module name (use command line). 
m_wszTempBuffer, // Command line. 
NULL,             // Process handle not inheritable. 
NULL,             // Thread handle not inheritable. 
FALSE,            // Set handle inheritance to FALSE. 
0,                // No creation flags. 
NULL,             // Use parent's environment block. 
NULL,             // Use parent's starting directory. 
&si,              // Pointer to STARTUPINFO structure.
&pi )             // Pointer to PROCESS_INFORMATION structure.

{
CString sErrorMessage = _T("Fail to run PilotEdit: ");
MessageBox(NULL,sErrorMessage + m_wszTempBuffer, _T("PilotEdit"), MB_OK); 
}
}
return S_OK;
}

解决方案 »

  1.   

    知道原因了,需要在InvokeCommand判断当前命令。HRESULT CEShellExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )
    {
    //If pCmdInfo->lpVerb points to a string and pCmdInfo->lpVerb is not "PilotEdit", return E_INVALIDARG
    if (0 != HIWORD( pCmdInfo->lpVerb) && strcmp(pCmdInfo->lpVerb, "PilotEdit") != 0)
    {
    return E_INVALIDARG;
    }