Basic support for installing custom service files

master
Richard Stanway 2015-05-08 23:50:44 +02:00
parent eff0486437
commit 42adfc7183
8 changed files with 204 additions and 14 deletions

View File

@ -287,6 +287,7 @@
<ClCompile Include="Source\GlobalSource.cpp" />
<ClCompile Include="Source\HTTPClient.cpp" />
<ClCompile Include="Source\ImageProcessing.cpp" />
<ClCompile Include="Source\InstallService.cpp" />
<ClCompile Include="Source\ReplayBuffer.cpp" />
<ClCompile Include="Source\libnsgif.c" />
<ClCompile Include="Source\LogUploader.cpp" />

View File

@ -160,6 +160,9 @@
<ClCompile Include="Source\Service.cpp">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="Source\InstallService.cpp">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Source\D3D10System.h">

154
Source/InstallService.cpp Normal file
View File

@ -0,0 +1,154 @@
/********************************************************************************
Copyright (C) 2015 Richard Stanway <r1ch@obsproject.com>
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************/
#include "Main.h"
bool InstallUserService(TCHAR *path)
{
XConfig serverData;
if (serverData.Open(path))
{
XElement *services = serverData.GetRootElement();
if (services)
{
auto numServices = services->NumElements();
if (numServices != 1)
return false;
auto service = services->GetElementByID(0);
if (!service)
return false;
CTSTR name = service->GetName();
auto servers = service->GetElement(TEXT("servers"));
if (!servers || !servers->NumDataItems())
return false;
String confirmMessage = FormattedString(Str("InstallServiceConfirm"), name);
confirmMessage.FindReplace(TEXT("$1"), name);
String uninstallMessage = FormattedString(Str("InstallServiceAlreadyInstalled"), name);
uninstallMessage.FindReplace(TEXT("$1"), name);
serverData.Close();
CTSTR serviceFileName = srchr(path, '\\');
if (serviceFileName)
serviceFileName++;
else
return false;
String baseFilename = serviceFileName;
baseFilename.FindReplace(TEXT(".obs-service"), TEXT(""));
String destination = FormattedString(TEXT("%s\\services\\%s.xconfig"), lpAppDataPath, baseFilename.Array());
if (OSFileExists(destination.Array()))
{
if (OBSMessageBox(NULL, uninstallMessage.Array(), L"Open Broadcaster Software", MB_ICONQUESTION | MB_YESNO) == IDYES)
OSDeleteFile(destination.Array());
return true;
}
if (OBSMessageBox(NULL, confirmMessage.Array(), L"Open Broadcaster Software", MB_ICONQUESTION | MB_YESNO) == IDYES)
{
if (!OSCopyFile(destination.Array(), path))
{
OBSMessageBox(NULL, FormattedString(TEXT("Failed to copy service file: error %d"), GetLastError()), L"Open Broadcaster Software", MB_ICONERROR);
return false;
}
else
{
OBSMessageBox(NULL, Str("InstallServiceInstalled"), L"Open Broadcaster Software", MB_ICONINFORMATION);
return true;
}
}
else
return false;
}
else
return false;
}
return false;
}
void RegisterServiceFileHandler(void)
{
// the Win32 API seems to be lacking a nice way to register file extensions
// so we just try to register it every time.
HKEY hk, newKey;
if (RegOpenCurrentUser(KEY_WRITE, &hk) != ERROR_SUCCESS)
return;
if (RegCreateKeyEx(hk, L"Software\\Classes\\.obs-service", 0, NULL, 0, KEY_WRITE, NULL, &newKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hk);
return;
}
RegSetValue(newKey, NULL, REG_SZ, L"OpenBroadcasterSoftware", 0);
RegSetValue(newKey, L"Content Type", REG_SZ, L"application/x-obs-service", 0);
RegCloseKey(newKey);
if (RegCreateKeyEx(hk, L"Software\\Classes\\OpenBroadcasterSoftware\\Content Type", 0, NULL, 0, KEY_WRITE, NULL, &newKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hk);
return;
}
RegSetValue(newKey, NULL, REG_SZ, L"application/x-obs-service", 0);
RegCloseKey(newKey);
if (RegCreateKeyEx(hk, L"Software\\Classes\\OpenBroadcasterSoftware\\shell", 0, NULL, 0, KEY_WRITE, NULL, &newKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hk);
return;
}
RegSetValue(newKey, NULL, REG_SZ, L"install", 0);
RegCloseKey(newKey);
if (RegCreateKeyEx(hk, L"Software\\Classes\\OpenBroadcasterSoftware\\shell\\install", 0, NULL, 0, KEY_WRITE, NULL, &newKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hk);
return;
}
RegSetValue(newKey, NULL, REG_SZ, L"Install Service", 0);
RegCloseKey(newKey);
if (RegCreateKeyEx(hk, L"Software\\Classes\\OpenBroadcasterSoftware\\shell\\install\\command", 0, NULL, 0, KEY_WRITE, NULL, &newKey, NULL) != ERROR_SUCCESS)
{
RegCloseKey(hk);
return;
}
String modulePath;
modulePath.SetLength(MAX_PATH);
if (GetModuleFileName(NULL, modulePath, modulePath.Length() - 1))
RegSetValue(newKey, NULL, REG_SZ, FormattedString(TEXT("\"%s\" -installservice \"%%1\""), modulePath.Array()), 0);
RegCloseKey(newKey);
RegCloseKey(hk);
}

View File

@ -471,6 +471,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
LPWSTR *args = CommandLineToArgvW(GetCommandLineW(), &numArgs);
LPWSTR profile = NULL;
LPWSTR sceneCollection = NULL;
LPWSTR userService = NULL;
bool bDisableMutex = false;
@ -492,6 +493,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
if (++i < numArgs)
sceneCollection = args[i];
}
else if (scmpi(args[i], L"-installservice") == 0)
{
if (++i < numArgs)
{
bDisableMutex = true;
userService = args[i];
}
}
}
//------------------------------------------------------------
@ -601,6 +610,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
lpAllocator = (TSTR)malloc(size);
mcpy(lpAllocator, strAllocator.Array(), size);
}
RegisterServiceFileHandler();
}
if(lpAllocator)
@ -615,6 +626,30 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
//EnableMemoryTracking(true, 8961);
//-----------------------------------------------------
// load locale
if (!locale->LoadStringFile(TEXT("locale/en.txt")))
AppWarning(TEXT("Could not open locale string file '%s'"), TEXT("locale/en.txt"));
String strLanguage = GlobalConfig->GetString(TEXT("General"), TEXT("Language"), TEXT("en"));
if (!strLanguage.CompareI(TEXT("en")))
{
String langFile;
langFile << TEXT("locale/") << strLanguage << TEXT(".txt");
if (!locale->LoadStringFile(langFile))
AppWarning(TEXT("Could not open locale string file '%s'"), langFile.Array());
}
// install user service here after we've loaded XT and locale
if (userService)
{
if (!InstallUserService(userService))
return 1;
return 0;
}
//--------------------------------------------
GlobalConfig->SetString(TEXT("General"), TEXT("LastAppDirectory"), lpAppPath);

View File

@ -150,21 +150,8 @@ OBS::OBS()
InitVolumeControl(hinstMain);
InitVolumeMeter(hinstMain);
//-----------------------------------------------------
// load locale
if(!locale->LoadStringFile(TEXT("locale/en.txt")))
AppWarning(TEXT("Could not open locale string file '%s'"), TEXT("locale/en.txt"));
// still need this here for API
strLanguage = GlobalConfig->GetString(TEXT("General"), TEXT("Language"), TEXT("en"));
if(!strLanguage.CompareI(TEXT("en")))
{
String langFile;
langFile << TEXT("locale/") << strLanguage << TEXT(".txt");
if(!locale->LoadStringFile(langFile))
AppWarning(TEXT("Could not open locale string file '%s'"), langFile.Array());
}
//-----------------------------------------------------
// load classes

View File

@ -556,6 +556,9 @@ std::pair<std::unique_ptr<XConfig>, XElement*> LoadService(const ServiceIdentifi
std::pair<std::unique_ptr<XConfig>, XElement*> LoadService(String *failReason=nullptr);
ServiceIdentifier GetCurrentService();
bool InstallUserService(TCHAR *path);
void RegisterServiceFileHandler(void);
//----------------------------
struct StatusBarDrawData

View File

@ -543,6 +543,7 @@ INT_PTR SettingsPublish::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
data.mode = mode;
//--------------------------------------------
services.empty();
hwndTemp = GetDlgItem(hwnd, IDC_SERVICE);
int itemId = (int)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Custom"));
@ -554,6 +555,9 @@ INT_PTR SettingsPublish::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam)
EnumerateServices([&](ServiceIdentifier sid, XElement *service)
{
if (!service)
return true;
services.emplace_back(sid);
auto pos = duplicates.find(service->GetName());
int id;

View File

@ -44,6 +44,9 @@ StreamReport="Stream Report"
MessageBoxWarningCaption="Warning"
NoSourcesFound="You haven't added any sources! Are you sure you want to stream a black screen?"
StreamClosePending="Stream or file output unfinished, closing OBS may cause the stream to end prematurely or the file to be corrupted. Do you want to wait another 15 seconds for the output to finish?"
InstallServiceConfirm="Do you want to add streaming service '$1' to the OBS services list?"
InstallServiceAlreadyInstalled="Streaming service '$1' is already installed. Would you like to uninstall it?"
InstallServiceInstalled="The streaming service has been installed. You can find it in Settings / Broadcast Settings."
ImportGlobalSourceNameExists="The global source '$1' already exists in the current scene collection."
ImportGlobalSources="Import Global Sources"