Выгрузка-загрузка профилей пользователя

Предлагаю решение несложной, в общем-то задачи: как сохранять и загружать профили пользователей. Скажем, нужно, чтобы один пользователь профиль настроил, а остальные эти настройки себе загрузили. Или, к примеру, существует необходимость работать с разными профилями: в одном видны такие-то поля, в другом - другие. Или... словом, был бы ключ, а дверь найдётся.

Каталог, где хранится профиль пользователя, можно получить используя свойство Connector.ProfileDirectory. В этом каталоге находится набор файлов *.dat, где и записаны настройки. Таким образом, переброска профиля сводится, в первом приближении, к копированию и перезаписи этих файлов. Стоит также принять во внимание, что при выходе из программы профили автоматически перезаписываются (сохраняются текущие настройки), поэтому после загрузки профиля следует предусмотреть отключение этой перезаписи.

Для решения задачи я создал два дополнительных действия (ActionMenuItem) в wnd_Main, назвав их amiProfileLoad и amiProfileSave с понятными пользователю заголовками. По событию OnExecute в scr_Main выполнялись следующие действия:

function amiProfileLoadOnExecute(ActionMenuItem, Sender) {
//Загрузка профиля из каталога
        var DirName = System.CreateObject('TSObjectLibrary.Value');    
        if (!(System.selectDirectory('Открыть папку, где хранится профиль', '', DirName))) {
           return;     
        }
        var SelectedDirName = new String(DirName.Value);//Здесь имя выбранной папки
        var ProfileDir = new String(Connector.ProfileDirectory);//Здесь имя папки, где хранится профиль
        ProfileDir = ProfileDir.slice(0, ProfileDir.length-1);
        //Копируем из этой папки всё в папку профиля
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        fso.CopyFolder (SelectedDirName, ProfileDir);
        ShowInformationDialog('Профиль загружен успешно. \nЧтобы изменения вступили в силу, необходимо перезапустить программу.')
        Self.Attributes('ProfileLoaded') = true; //Чтобы при выходе загруженный профиль не затирался текущим
}

function amiProfileSaveOnExecute(ActionMenuItem, Sender) {
// Выгрузка профиля в каталог каталога  
    var DirName = System.CreateObject('TSObjectLibrary.Value');
        if (!(System.selectDirectory('Открыть папку, куда следует поместить текущий профиль', '', DirName))) {   
           return;     
        }
        var SelectedDirName = new String(DirName.Value);//Здесь имя выбранной папки
        var ProfileDir = new String(Connector.ProfileDirectory);//Здесь имя папки, где хранится профиль
        ProfileDir = ProfileDir.slice(0, ProfileDir.length-1);
        //Копируем из этой папки всё в папку профиля
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        fso.CopyFolder (ProfileDir, SelectedDirName);
        ShowInformationDialog('Профиль сохранён в каталоге \n'+SelectedDirName);       
}

Чтобы при выходе загруженный профиль не затирался текущим, надо в функции того же скрипта поставить проверку значения присвоенного атрибута:

function CloseMainForm() {
        Timer.IsEnabled = false;
        Self.Attributes('CallCentreClientWindow') = null;
        CollectGarbage(0.001);
        WinCache_Clear();
        ReleaseMailUtils();
        wndWorkspace.Window = System.EmptyValue;
        if (!Self.Attributes('ProfileLoaded')){//--Добавлено         
                var Keys = (new VBArray(Main.Workspaces.Keys()).toArray());
                for (var i in Keys) {
                        var Key = Keys[i];
                        var Workspace = Main.Workspaces(Key);
                        if (Workspace) {
                                Services.SerializeItemToProfile(Workspace, EmptyStr);
                        }
                }
        } else {//--Добавлено
                Self.Attributes('ProfileLoaded') = false;//--Добавлено
        }//--Добавлено
        ClearTemporaryFiles();
        Self.Attributes.Clear();
}

Предлагаемое решение не обладает "дуракоустойчивостью", и если пользователь при загрузке выберет "не тот" каталог, то его содержимое всё равно будет пернесено в каталог профиля. Благо, на нормальной работе это, по-видимому, не отразится, так как старый профиль не будет затёрт.

Нравится

Поделиться

2 комментария

Я решил эту задачу проще - состряпал дополнительный "сервис". Всё ясно по исходникам, просто как грабли. wnd_Main и scr_Main приведены для примера встраивания сей поделки в общий интерфейс.Можно сделать красивей, но лень...cloneprofile.zip

"Никиреев Сергей" написал:Можно сделать красивей, но лень

Спасибо, Сергей, за выложенные исходники.
Сделал красивей + кое-что подрихтовал (как для себя сделал), прикрепил в архиве сервисы.

Внешний вид:
внешний вид

Вызов:

function amiCloneProfileOnExecute(ActionMenuItem, Sender) {
	if ((Connector.CurrentUser.IsAdmin || Connector.CurrentUser.IsSysAdmin)) {
	 	var UsersWindow = Services.GetNewItemByUSI('wnd_CloneProfile');
		UsersWindow.Prepare();
		UsersWindow.Show();
	}
	else {
	   ShowWarningDialog('У Вас нет прав для выполнения этого действия!');
	}
}

У меня работает на версии 3.4.1.

Показать все комментарии