Quantcast
Channel: Visual Studio Integrate forum
Viewing all articles
Browse latest Browse all 4410

Opening Files in a Single Instance Isolated Shell Standalone

$
0
0

Hi,

we have built a standalone application based on the Visual Studio Isolated Shell. We would like this to be single instance so that when you click an associated file type it will open that file in an already existing instance of our isolated shell application. I've written the code to do this in our :

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	try {
		// Try to open the mutex.
		HANDLE hMutex = OpenMutex(
			MUTEX_ALL_ACCESS, 0, L"MyStudio");

		// If hMutex is 0 then the mutex doesn't exist.
		if (!hMutex)
			hMutex = CreateMutex(0, 0, L"MyStudio");
		else {
			// This is a second instance. Bring the 
			// original instance to the top.
			HWND hWnd = FindWindow(0, L"MyStudio");
			SetForegroundWindow(hWnd);

			// Command line is not empty. Send the 
			// command line in a WM_COPYDATA message.
			if (strlen(lpCmdLine) != 0) {
				COPYDATASTRUCT cds;
				cds.cbData = strlen(lpCmdLine);
				cds.lpData = lpCmdLine;
				SendMessage(
					hWnd, WM_COPYDATA, 0, (LPARAM)&cds);
			}

			return 0;
		}

		UNREFERENCED_PARAMETER(hPrevInstance);
		UNREFERENCED_PARAMETER(lpCmdLine);

		int nRetVal = -1;
		WCHAR szExeFilePath[MAX_PATH];
		HKEY hKeyAppEnv10Hive = NULL;

		if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\AppEnv\\10.0", 0, KEY_READ, &hKeyAppEnv10Hive) == ERROR_SUCCESS)
		{
			DWORD dwType;
			DWORD dwSize = MAX_PATH;
			RegQueryValueExW(hKeyAppEnv10Hive, L"AppenvStubDLLInstallPath", NULL, &dwType, (LPBYTE)szExeFilePath, &dwSize);
			RegCloseKey(hKeyAppEnv10Hive);
		}

		if(GetFileAttributesW(szExeFilePath) == INVALID_FILE_ATTRIBUTES)
		{
			//If we cannot find it at a registered location, then try in the same directory as the application
			GetModuleFileNameW(NULL, szExeFilePath, MAX_PATH);
			WCHAR *pszStartOfFileName = wcsrchr(szExeFilePath, '\\');
			if(!pszStartOfFileName)
			{
				return -1;
			}
			*pszStartOfFileName = 0;
			wcscat_s(szExeFilePath, MAX_PATH, L"\\appenvstub.dll");

			if(GetFileAttributesW(szExeFilePath) == INVALID_FILE_ATTRIBUTES)
			{
				//If the file cannot be found in the same directory as the calling exe, then error out.
				//ShowNoComponentError(hInstance);
				WCHAR szErrorString[1000];
				WCHAR szCaption[1000];
				LoadStringW(hInstance, IDS_ERR_MSG_INVALID_FILE_ATTRIBUTES, szErrorString, 1000);
				LoadStringW(hInstance, IDS_ERR_FATAL_CAPTION, szCaption, 1000);
				MessageBoxW(NULL, szErrorString, szCaption, MB_OK|MB_ICONERROR);
				return -1;
			}
		}
		//Get full Unicode command line to pass to StartWithCommandLine function.
		LPWSTR lpwCmdLine = GetCommandLineW();

		HMODULE hModStubDLL = LoadLibraryW(szExeFilePath);
		if(!hModStubDLL)
		{
			//ShowNoComponentError(hInstance);
			WCHAR szErrorString[1000];
			WCHAR szCaption[1000];
			LoadStringW(hInstance, IDS_ERR_MSG_LOAD_LIBRARY, szErrorString, 1000);
			LoadStringW(hInstance, IDS_ERR_FATAL_CAPTION, szCaption, 1000);
			MessageBoxW(NULL, szErrorString, szCaption, MB_OK|MB_ICONERROR);
			return -1;
		}

		StartWithCommandLineFCN StartWithCommandLine = (StartWithCommandLineFCN)GetProcAddress(hModStubDLL, "Start");
		if(!StartWithCommandLine)
		{
			//ShowNoComponentError(hInstance);
			WCHAR szErrorString[1000];
			WCHAR szCaption[1000];
			LoadStringW(hInstance, IDS_ERR_MSG_START_WITH, szErrorString, 1000);
			LoadStringW(hInstance, IDS_ERR_FATAL_CAPTION, szCaption, 1000);
			MessageBoxW(NULL, szErrorString, szCaption, MB_OK|MB_ICONERROR);
			return -1;
		}

		nRetVal = StartWithCommandLine(lpwCmdLine, L"MyStudio", nCmdShow, NULL, NULL);

		FreeLibrary(hModStubDLL);
		ReleaseMutex(hMutex);
		return nRetVal;
	}
	catch (...) {
		return -1;
	}
}

The Mutex mechanism works well, and I get my existing application pop into the foreground, but I can't get it to use the command line that I am passing to it - I'm using WM_COPYDATA above - this doesn't work and is just an example of what I could do with the data.

How do I pass the command line to the existing instance and get the existing instance to open the files specified on the command line?


Viewing all articles
Browse latest Browse all 4410

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>