[vlc-devel] libvlc on windows

Mark Vejvoda mark_vejvoda at hotmail.com
Mon May 14 05:35:56 CEST 2012


First things first, thanks for making a truly great piece of software.

I work on the totally (as in Debian friendly) free open source game
called megaglest (megaglest.org). This weekend i added support to play
videos using libvlc. On Linux this was a piece of cake (as it should
be :)), but on windows it was a nightmare.

I fired up my trusty Virtualbox virtual machine to load my Windows XP
image (I would never dirty myself or my hardware by actually devoting
anything serious to a Windows platform) and began porting my work to
compile in VC++ 2010 express in this VM. I am working on libvlc 2.0.1
and followed the directions to create a lib file and compiled perfectly
fine. Unfortunately when i tried to test libvlc on windows i had loads
of problems spending days to solve it for this evil platform.

The bottom line is that libvlc either wants the plugins folder in the
same folder as my binary or optionally it checks the VLC_PLUGIN_PATH
environment variable. Environment variable management is hideously evil
on Windows. Googling endlessly I tried everything remotely possibly to
get me code working, but nothing worked, i kept getting error from
libvlc that it could not find plugins. Setting he env var manually in
the command prompt DID work, but trying to control this within my
application was impossible! Using VC++ and calling _putenv() only works
on the current process, and by the time the binary loads, libvlc has
already loaded during program ini and did not find the plugins. I tried
editing registry values and broadcasting to the OS to refresh
environment vars, none of this works, its all an evil Microsoft
conspiracy! In the end if i set the env var using _putenv then re-launch
myself, the new binary inherits the env var i just set and finally
works. THERE WAS NO OTHER WAY to get this working, i tired many
alternatives.

I highly suggest adding back the arg --plugin_path so that developers
using libvlc can programmatically tell libvlc where to look for the
plugins path, as this will make things much easier for everyone.

Here is the code I have at the top of main() (the only relevant working
code is getting the path to VLC then calling _putenv() then _execv()


#if defined(WIN32)
	//printf("*** VLC START ****\n");
	//if(verboseEnabled) printf("Trying [%s]\n",getenv("VLC_PLUGIN_PATH"));
	if(getenv("VLC_PLUGIN_PATH") == NULL) {
		//printf("*** VLC C ****\n");

		// For windows check registry for install path
		std::string strValue = getRegKey("Software\\VideoLAN\\VLC",
"InstallDir");
		if(strValue != "") {
			if(strValue.length() >= 2) {
				if(strValue[0] == '"') {
					strValue = strValue.erase(0);
				}
				if(strValue[strValue.length()-1] == '"') {
					strValue = strValue.erase(strValue.length()-1);
				}
				if(strValue[strValue.length()-1] != '\\') {
					strValue += "\\";
				}
			}
			strValue += "plugins";
			string newstrValue = "VLC_PLUGIN_PATH=" + strValue;
			_putenv(newstrValue.c_str());
			//bool result =
SetEnvironmentVariableA("VLC_PLUGIN_PATH",strValue.c_str());
			
			//Open the registry key.
			wstring subKey = L"Environment";
			HKEY keyHandle;
			DWORD dwDisposition;
			RegCreateKeyEx(HKEY_CURRENT_USER,subKey.c_str(),0, NULL, 0,
KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition);
			//Set the value.
			std::auto_ptr<wchar_t> wstr(Ansi2WideString(strValue.c_str()));
	
			wstring vlcPluginPath = wstring(wstr.get());
			DWORD len = (DWORD) sizeof(wchar_t) * vlcPluginPath.length() + 1;
			RegSetValueEx(keyHandle, L"VLC_PLUGIN_PATH", 0, REG_SZ,
(PBYTE)vlcPluginPath.c_str(), len);
			RegCloseKey(keyHandle);

			subKey = L"System\\CurrentControlSet\\Control\\Session Manager\
\Environment";
			RegCreateKeyEx(HKEY_LOCAL_MACHINE,subKey.c_str(),0, NULL, 0,
KEY_ALL_ACCESS, NULL, &keyHandle, &dwDisposition);
			//Set the value.
			wstr.reset(Ansi2WideString(strValue.c_str()));
			vlcPluginPath = wstring(wstr.get());
			len = (DWORD) sizeof(wchar_t) * vlcPluginPath.length() + 1;
			RegSetValueEx(keyHandle, L"VLC_PLUGIN_PATH", 0, REG_SZ,
(PBYTE)vlcPluginPath.c_str(), len);
			RegCloseKey(keyHandle);

			RegFlushKey(keyHandle);

			string test = "SET " + newstrValue;
			system(test.c_str());
			DWORD dwReturnValue=0;
			LRESULT error1 = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE,
0, (LPARAM)
				L"Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);
			//SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)
"Environment", SMTO_ABORTIFHUNG, 10000, NULL );
			//SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)
L"Environment", SMTO_ABORTIFHUNG, 10000, NULL );
			//SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)
TEXT("Environment"), SMTO_ABORTIFHUNG,10000, &dwReturnValue);

			//printf("*** VLC D [%s] error1 = %d dwReturnValue = %d ****
\n",getenv("VLC_PLUGIN_PATH"),error1,dwReturnValue);
			//system(argv[0]);
			const char *const *newargv = &argv[1];
			 _execv( argv[0], newargv );
			return 0;
		}
	}
#endif





More information about the vlc-devel mailing list