博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dynamics 365 WebResourceUtility 工具更新
阅读量:6152 次
发布时间:2019-06-21

本文共 48119 字,大约阅读时间需要 160 分钟。

Dynamics 365 SDK/Tools/WebResourceUtility 是一个非常实用的工具,

在开发WebResource脚本时,常常需要把本地开发上传到开发环境,实用此工具不需要打开CRM找到具体的WebResource上传然后再发布,

利用此工具可以批量上传本地代码到开发环境并自动发布已上传的代码。

但工具包本身包含一些问题,幸好工具包提供源码,我修复了部分问题,支持OnPremise / IFD / Online Office365部署。

Update point:

  1. only publish WebResources which already uploaded.
  2. fixed authentication failed issue.
  3. support office 365 authenticate.
  4. online federation authenticate has been commented. 

ConsolelessServerConnection.cs

using System;using System.Collections.Generic;using System.ServiceModel.Description;using System.Linq;// These namespaces are found in the Microsoft.Xrm.Sdk.dll assembly// located in the SDK\bin folder of the SDK download.using Microsoft.Xrm.Sdk.Client;using Microsoft.Xrm.Sdk.Discovery;using Microsoft.Xrm.Sdk;using System.DirectoryServices.AccountManagement;namespace Microsoft.Crm.Sdk.Samples{    public class ConsolelessServerConnection : ServerConnection    {        #region Private properties        private Configuration config = new Configuration();        #endregion Private properties        public virtual ServerConnection.Configuration GetServerConfiguration(string server, string orgName, string user, string pw, string domain )        {            config.ServerAddress = server;            if (config.ServerAddress.EndsWith(".dynamics.com"))            {                config.EndpointType = AuthenticationProviderType.LiveId;                config.DiscoveryUri =                    new Uri(String.Format("https://disco.{0}/XRMServices/2011/Discovery.svc", config.ServerAddress.Replace(orgName+".","")));                config.DeviceCredentials = GetDeviceCredentials();                ClientCredentials credentials = new ClientCredentials();                credentials.UserName.UserName = user;                credentials.UserName.Password = pw;                                config.Credentials = credentials;                config.OrganizationUri = GetOrganizationAddress(config.DiscoveryUri, orgName);            }            else if (config.ServerAddress.EndsWith(".com"))            {                config.EndpointType = AuthenticationProviderType.Federation;                config.DiscoveryUri =                    new Uri(String.Format("https://{0}/XRMServices/2011/Discovery.svc", config.ServerAddress));                ClientCredentials credentials = new ClientCredentials();                credentials.Windows.ClientCredential = new System.Net.NetworkCredential(user, pw, domain);                config.Credentials = credentials;                config.OrganizationUri = GetOrganizationAddress(config.DiscoveryUri, orgName);            }            else            {                config.EndpointType = AuthenticationProviderType.ActiveDirectory;                config.DiscoveryUri =                    new Uri(String.Format("http://{0}/XRMServices/2011/Discovery.svc", config.ServerAddress));                ClientCredentials credentials = new ClientCredentials();                credentials.Windows.ClientCredential = new System.Net.NetworkCredential(user, pw, domain);                config.Credentials = credentials;                config.OrganizationUri = GetOrganizationAddress(config.DiscoveryUri, orgName);            }            if (configurations == null) configurations = new List
(); configurations.Add(config); return config; } public DiscoveryServiceProxy GetDiscoveryServiceProxy(Uri discoveryServiceUri) { IServiceManagement
serviceManagement = ServiceConfigurationFactory.CreateManagement
( discoveryServiceUri); AuthenticationProviderType endpointType = serviceManagement.AuthenticationType; AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType); String organizationUri = String.Empty; return GetProxy
(serviceManagement, authCredentials); } public OrganizationServiceProxy GetOrganizationServiceProxy(Uri discoveryServiceUri, string orgName) { IServiceManagement
serviceManagement = ServiceConfigurationFactory.CreateManagement
( discoveryServiceUri); AuthenticationProviderType endpointType = serviceManagement.AuthenticationType; AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType); String organizationUri = String.Empty; // Get the discovery service proxy. using (DiscoveryServiceProxy discoveryProxy = GetProxy
(serviceManagement, authCredentials)) { if (discoveryProxy != null) { // Obtain information about the organizations that the system user belongs to. OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy); OrganizationDetail org = orgs.Where(x => x.UniqueName.ToLower() == orgName.ToLower()).FirstOrDefault(); if (org != null) { Uri orgUri = new System.Uri(org.Endpoints[EndpointType.OrganizationService]); IServiceManagement
orgServiceManagement = ServiceConfigurationFactory.CreateManagement
(orgUri); // Set the credentials. AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType); return GetProxy
(orgServiceManagement, credentials); } else { throw new InvalidOperationException("That OrgName does not exist on that server."); } } else throw new Exception("An invalid server name was specified."); } } protected virtual Uri GetOrganizationAddress(Uri discoveryServiceUri, string orgName) { IServiceManagement
serviceManagement = ServiceConfigurationFactory.CreateManagement
( discoveryServiceUri); AuthenticationProviderType endpointType = serviceManagement.AuthenticationType; AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType); String organizationUri = String.Empty; // Get the discovery service proxy. using (DiscoveryServiceProxy discoveryProxy = GetProxy
(serviceManagement, authCredentials)) { // Obtain organization information from the Discovery service. if (discoveryProxy != null) { // Obtain information about the organizations that the system user belongs to. OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy); OrganizationDetail org = orgs.Where(x => x.UrlName.ToLower() == orgName.ToLower()).FirstOrDefault(); if (org != null) { return new System.Uri(org.Endpoints[EndpointType.OrganizationService]); } else { throw new InvalidOperationException("That OrgName does not exist on that server."); } } else throw new Exception("An invalid server name was specified."); } } #region CustomFunctions 修改获取发现服务或组织服务代码 public OrganizationServiceProxy GetOrganizationServiceProxy(Uri orgUri, AuthenticationProviderType endpointType) { IServiceManagement
orgServiceManagement = ServiceConfigurationFactory.CreateManagement
(orgUri); // Set the credentials. AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType); return GetProxy
(orgServiceManagement, credentials); } ///
/// Generic method to obtain discovery/organization service proxy instance. /// ///
/// Set IDiscoveryService or IOrganizationService type to request respective service proxy instance. ///
///
/// Set the return type to either DiscoveryServiceProxy or OrganizationServiceProxy type based on TService type. ///
///
An instance of IServiceManagement ///
The user's Microsoft Dynamics CRM logon credentials. ///
///
public TProxy GetProxy
( IServiceManagement
serviceManagement, AuthenticationCredentials authCredentials) where TService : class where TProxy : ServiceProxy
{ Type classType = typeof(TProxy); if (serviceManagement.AuthenticationType != AuthenticationProviderType.ActiveDirectory) { AuthenticationCredentials tokenCredentials = serviceManagement.Authenticate(authCredentials); // Obtain discovery/organization service proxy for Federated, LiveId and OnlineFederated environments. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and SecurityTokenResponse. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(SecurityTokenResponse) }) .Invoke(new object[] { serviceManagement, tokenCredentials.SecurityTokenResponse }); } // Obtain discovery/organization service proxy for ActiveDirectory environment. // Instantiate a new class of type using the 2 parameter constructor of type IServiceManagement and ClientCredentials. return (TProxy)classType .GetConstructor(new Type[] { typeof(IServiceManagement
), typeof(ClientCredentials) }) .Invoke(new object[] { serviceManagement, authCredentials.ClientCredentials }); } //
///
/// Obtain the AuthenticationCredentials based on AuthenticationProviderType. /// ///
A service management object. ///
An AuthenticationProviderType of the CRM environment. ///
Get filled credentials.
public AuthenticationCredentials GetCredentials
(IServiceManagement
service, AuthenticationProviderType endpointType) { AuthenticationCredentials authCredentials = new AuthenticationCredentials(); switch (endpointType) { case AuthenticationProviderType.ActiveDirectory: authCredentials.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(config.Credentials.UserName.UserName, config.Credentials.UserName.Password, config.Credentials.Windows.ClientCredential.Domain); break; case AuthenticationProviderType.LiveId: authCredentials.ClientCredentials.UserName.UserName = config.Credentials.UserName.UserName; authCredentials.ClientCredentials.UserName.Password = config.Credentials.UserName.Password; authCredentials.SupportingCredentials = new AuthenticationCredentials(); authCredentials.SupportingCredentials.ClientCredentials = Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice(); break; default: // For Federated and OnlineFederated environments. authCredentials.ClientCredentials.UserName.UserName = config.Credentials.UserName.UserName; authCredentials.ClientCredentials.UserName.Password = config.Credentials.UserName.Password; // For OnlineFederated single-sign on, you could just use current UserPrincipalName instead of passing user name and password. //authCredentials.UserPrincipalName = UserPrincipal.Current.UserPrincipalName; // Windows Kerberos //The service is configured for User Id authentication, but the user might provide Microsoft //account credentials.If so, the supporting credentials must contain the device credentials. if (endpointType == AuthenticationProviderType.OnlineFederation) { IdentityProvider provider = service.GetIdentityProvider(authCredentials.UserPrincipalName); if (provider != null && provider.IdentityProviderType == IdentityProviderType.LiveId) { authCredentials.SupportingCredentials = new AuthenticationCredentials(); authCredentials.SupportingCredentials.ClientCredentials = Microsoft.Crm.Services.Utility.DeviceIdManager.LoadOrRegisterDevice(); } } break; } return authCredentials; } #endregion }}

  MainWindowViewModel.cs

using System;using System.Collections;using System.Collections.Generic;using System.Collections.ObjectModel;using System.IO;using System.Linq;using System.Text;using System.Windows;using System.Windows.Data;using System.Windows.Input;using System.Xml.Linq;using Microsoft.Crm.Sdk.Messages;using Microsoft.Xrm.Sdk;using Microsoft.Xrm.Sdk.Client;using Microsoft.Xrm.Sdk.Query;using WebResourceUtility.Model;using System.Text.RegularExpressions;using System.ComponentModel;using System.Windows.Threading;namespace Microsoft.Crm.Sdk.Samples{    public class MainWindowViewModel : ViewModelBase    {        #region Commands        RelayCommand _hideOutputWindow;        public ICommand HideOutputWindow         {            get            {                if (_hideOutputWindow == null)                {                    _hideOutputWindow = new RelayCommand(                        param => { IsOutputWindowDisplayed = false; });                }                return _hideOutputWindow;            }        }        RelayCommand _showOutputWindow;        public ICommand ShowOutputWindow        {            get            {                if (_showOutputWindow == null)                {                    _showOutputWindow = new RelayCommand(                        param => { IsOutputWindowDisplayed = true; });                }                return _showOutputWindow;            }        }        RelayCommand _browseFolderCommand;        public ICommand BrowseFolderCommand         {            get            {                if (_browseFolderCommand == null)                {                    _browseFolderCommand = new RelayCommand(                        param => this.ShowBrowseFolderDialog());                }                return _browseFolderCommand;            }        }        RelayCommand _activateConnectionCommand;        public ICommand ActivateConnectionCommand         {            get            {                if (_activateConnectionCommand == null)                {                    _activateConnectionCommand = new RelayCommand(                        param => this.ActivateSelectedConfiguration(),                        param => this.CanActivateSelectedConfiguration());                }                return _activateConnectionCommand;            }        }        RelayCommand _createNewConnectionCommand;        public ICommand CreateNewConnectionCommand        {            get            {                if (_createNewConnectionCommand == null)                {                    _createNewConnectionCommand = new RelayCommand(                        param => this.CreateNewConfiguration());                }                return _createNewConnectionCommand;            }        }                        RelayCommand _deleteConnectionCommand;        public ICommand DeleteConnectionCommand        {            get            {                if (_deleteConnectionCommand == null)                {                    _deleteConnectionCommand = new RelayCommand(                        param => this.DeleteSelectedConfiguration());                }                return _deleteConnectionCommand;            }        }        RelayCommand _activateSolutionCommand;        public ICommand ActivateSolutionCommand        {            get            {                if (_activateSolutionCommand == null)                {                    _activateSolutionCommand = new RelayCommand(                        param => this.ActivateSelectedSolution());                }                return _activateSolutionCommand;            }        }        RelayCommand _activateSelectedPackageCommand;        public ICommand ActivateSelectedPackageCommand        {            get            {                if (_activateSelectedPackageCommand == null)                {                    _activateSelectedPackageCommand = new RelayCommand(                        param => this.ActivatePackage());                }                return _activateSelectedPackageCommand;            }        }        RelayCommand _createNewPackageCommand;        public ICommand CreateNewPackageCommand        {            get            {                if (_createNewPackageCommand == null)                {                    _createNewPackageCommand = new RelayCommand(                        param => this.CreateNewPackage());                }                return _createNewPackageCommand;            }        }        RelayCommand _deleteActivePackageCommand;        public ICommand DeleteActivePackageCommand        {            get            {                if (_deleteActivePackageCommand == null)                {                    _deleteActivePackageCommand = new RelayCommand(                        param => this.DeleteSelectedPackage());                }                return _deleteActivePackageCommand;            }        }        RelayCommand _saveActivePackageCommand;        public ICommand SaveActivePackageCommand        {            get            {                if (_saveActivePackageCommand == null)                {                    _saveActivePackageCommand = new RelayCommand(                        param => SavePackages());                }                return _saveActivePackageCommand;            }        }                    RelayCommand _refreshFilesCommand;        public ICommand RefreshFilesCommand        {            get            {                if (_refreshFilesCommand == null)                {                    _refreshFilesCommand = new RelayCommand(                        param => this.SearchAndPopulateFiles());                }                return _refreshFilesCommand;            }        }        RelayCommand _saveConnectionsCommand;        public ICommand SaveConnectionsCommand        {            get            {                if (_saveConnectionsCommand == null)                {                    _saveConnectionsCommand = new RelayCommand(                        param => SaveConfigurations());                }                return _saveConnectionsCommand;            }        }        RelayCommand
_convertFileToResourceCommand; public ICommand ConvertFileToResourceCommand { get { if (_convertFileToResourceCommand == null) { _convertFileToResourceCommand = new RelayCommand
(AddFilesToWebResources); } return _convertFileToResourceCommand; } } RelayCommand
_uploadWebResourcesCommand; public ICommand UploadWebResourcesCommand { get { if (_uploadWebResourcesCommand == null) { _uploadWebResourcesCommand = new RelayCommand
(UploadWebResources, param => CanUploadWebResource()); } return _uploadWebResourcesCommand; } } RelayCommand _uploadAllWebResourcesCommand; public ICommand UploadAllWebResourcesCommand { get { if (_uploadAllWebResourcesCommand == null) { _uploadAllWebResourcesCommand = new RelayCommand(param => UploadAllWebResources(), param => CanUploadWebResource()); } return _uploadAllWebResourcesCommand; } } RelayCommand
_deleteWebResourcesCommand; public ICommand DeleteWebResourcesCommand { get { if (_deleteWebResourcesCommand == null) { _deleteWebResourcesCommand = new RelayCommand
(DeleteSelectedWebResources); } return _deleteWebResourcesCommand; } } #endregion #region Properties public const string CONFIG_FILENAME = @"configurations.xml"; public const string PACKAGES_FILENAME = @"packages.xml"; public const string VALID_NAME_MSG = "ERROR: Web Resource names cannot contain spaces or hyphens. They must be alphanumeric and contain underscore characters, periods, and non-consecutive forward slash characters"; public XElement XmlPackageData; public XElement XmlConfigData; private StringBuilder _progressMessage; public String ProgressMessage { get { return _progressMessage.ToString(); } set { _progressMessage.AppendLine(value); OnPropertyChanged("ProgressMessage"); } } private int _tabControlSelectedIndex; public int TabControlSelectedIndex { get { return _tabControlSelectedIndex; } set { _tabControlSelectedIndex = value; OnPropertyChanged("TabControlSelectedIndex"); } } private bool _areAllButtonsEnabled = true; public bool AreAllButtonsEnabled { get { return _areAllButtonsEnabled; } set { _areAllButtonsEnabled = value; OnPropertyChanged("AreAllButtonsEnabled"); } } public bool IsActiveConnectionSet { get { return (ActiveConfiguration != null) ? true : false; } } public bool IsActiveSolutionSet { get { return (ActiveSolution != null) ? true : false; } } public bool IsActivePackageSet { get { return (ActivePackage != null) ? true : false; } } private bool _shouldPublishAllAfterUpload; public bool ShouldPublishAllAfterUpload { get { return _shouldPublishAllAfterUpload; } set { _shouldPublishAllAfterUpload = value; OnPropertyChanged("ShouldPublishAllAfterUpload"); } } private bool _isOutputWindowDisplayed = false; public bool IsOutputWindowDisplayed { get { return _isOutputWindowDisplayed; } set { _isOutputWindowDisplayed = value; OnPropertyChanged("IsOutputWindowDisplayed"); OnPropertyChanged("IsWorkstationDisplayed"); } } public bool IsWorkstationDisplayed { get { return !(IsOutputWindowDisplayed); } } private String _fileSearchText; public String FileSearchText { get { return _fileSearchText; } set { _fileSearchText = value; OnPropertyChanged("FileSearchText"); } } //WebResources Packages public ObservableCollection
Packages { get; set; } private XElement _selectedPackage; public XElement SelectedPackage { get { return _selectedPackage; } set { _selectedPackage = value; OnPropertyChanged("SelectedPackage"); } } private XElement _activePackage; public XElement ActivePackage { get { return _activePackage; } set { _activePackage = value; OnPropertyChanged("ActivePackage"); OnPropertyChanged("IsActivePackageSet"); } } private bool _isActivePackageDirty = false; public bool IsActivePackageDirty { get { return _isActivePackageDirty; } set { _isActivePackageDirty = value; OnPropertyChanged("IsActivePackageDirty"); } } //FileInfos for all potential resources in a directory public ObservableCollection
CurrentFiles { get; set; } public ObservableCollection
CurrentFilesSelected { get; set; } //Represents a collection of "WebResourceInfo" node from XML. public ObservableCollection
WebResourceInfos { get; set; } public ObservableCollection
WebResourceInfosSelected { get; set; } //Connections public ObservableCollection
Configurations { get; set; } private XElement _selectedConfiguration; public XElement SelectedConfiguration { get { return _selectedConfiguration; } set { _selectedConfiguration = value; OnPropertyChanged("SelectedConfiguration"); } } private XElement _activeConfiguration; public XElement ActiveConfiguration { get { return _activeConfiguration; } set { _activeConfiguration = value; OnPropertyChanged("ActiveConfiguration"); OnPropertyChanged("IsActiveConnectionSet"); } } //Solutions public ObservableCollection
UnmanagedSolutions { get; set; } private Solution _selectedSolution; public Solution SelectedSolution { get { return _selectedSolution; } set { _selectedSolution = value; OnPropertyChanged("SelectedSolution"); } } private Solution _activeSolution; public Solution ActiveSolution { get { return _activeSolution; } set { _activeSolution = value; OnPropertyChanged("ActiveSolution"); OnPropertyChanged("IsActiveSolutionSet"); } } //Active Publisher private Publisher _activePublisher; public Publisher ActivePublisher { get { return _activePublisher; } set { _activePublisher = value; OnPropertyChanged("ActivePublisher"); } } private bool _shouldPublishAllUploadedWebResource; ///
/// 是否更新已上传的WebResource /// public bool ShouldPublishAllUploadedWebResource { get { return _shouldPublishAllUploadedWebResource; } set { _shouldPublishAllUploadedWebResource = value; OnPropertyChanged("ShouldPublishAllUploadedWebResource"); } } #endregion #region Fields //CRM Data Provider private ConsolelessServerConnection _serverConnect; private static OrganizationServiceProxy _serviceProxy; private static OrganizationServiceContext _orgContext; BackgroundWorker worker; #endregion #region Constructor public MainWindowViewModel() { XDocument xmlPackagesDocument = XDocument.Load(PACKAGES_FILENAME); XmlPackageData = xmlPackagesDocument.Element("UtilityRoot"); XDocument xmlConfigurationsDocument = XDocument.Load(CONFIG_FILENAME); XmlConfigData = xmlConfigurationsDocument.Element("Configurations"); Configurations = new ObservableCollection
(); Packages = new ObservableCollection
(); UnmanagedSolutions = new ObservableCollection
(); CurrentFiles = new ObservableCollection
(); CurrentFilesSelected = new ObservableCollection
(); WebResourceInfos = new ObservableCollection
(); WebResourceInfosSelected = new ObservableCollection
(); //Begin loading the XML data LoadXmlData(); TabControlSelectedIndex = 0; _progressMessage = new StringBuilder(); _shouldPublishAllAfterUpload = false; _shouldPublishAllUploadedWebResource = true; List_UploadedWebResources = new List
(); //Set up the background worker to handle upload web resources. Helps //prevent the UI from locking up and can have a Console-like output window //with real-time display. worker = new BackgroundWorker(); worker.WorkerReportsProgress = true; worker.DoWork += new DoWorkEventHandler(BeginUpload); worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) { this.BeginInvoke(() => { AreAllButtonsEnabled = true; }); }; } #endregion #region Methods private void LoadXmlData() { LoadConfigurations(); LoadPackages(); } //Configuration Methods private void LoadConfigurations() { Configurations.Clear(); var configs = XmlConfigData.Descendants("Configuration"); foreach (var c in configs) { Configurations.Add(c); } } private void SaveConfigurations() { XmlConfigData.Descendants("Configuration").Remove(); XmlConfigData.Add(Configurations.ToArray()); XmlConfigData.Save(CONFIG_FILENAME); } private void CreateNewConfiguration() { XElement newConfig = new XElement("Configuration", new XAttribute("name", "New Connection"), new XAttribute("server", String.Empty), new XAttribute("orgName", String.Empty), new XAttribute("userName", String.Empty), new XAttribute("domain", String.Empty)); Configurations.Add(newConfig); SelectedConfiguration = Configurations[Configurations.Count - 1]; } private void DeleteSelectedConfiguration() { if (SelectedConfiguration != null) { //if trying to delete the configuration that is also active already, //let them by clearing ActiveConfiguration and solutions. if (SelectedConfiguration == ActiveConfiguration) { ClearActiveConfiguration(); ClearSolutions(); } //Finally clear the SelectedConfiguration and remove it from the list of Configurations. var toBeDeleted = Configurations.Where(x => x == SelectedConfiguration).FirstOrDefault(); if (toBeDeleted != null) { Configurations.Remove(toBeDeleted); SelectedConfiguration = null; } } } private void ClearActiveConfiguration() { ActiveConfiguration = null; } private void ActivateSelectedConfiguration() { //User may have already been connected to another org, disconnect them. ClearActiveConfiguration(); //Clear out any Solutions from the Solutions collection since they are //Configuration specfic. ClearSolutions(); //Instantiate new proxy. if it is successful, it will also //set the ActiveConfiguration and retrieve Solutions. InstantiateService(); } private bool CanActivateSelectedConfiguration() { if (SelectedConfiguration != null && !String.IsNullOrWhiteSpace(SelectedConfiguration.Attribute("server").Value) && !String.IsNullOrWhiteSpace(SelectedConfiguration.Attribute("orgName").Value)) { return true; } return false; } //Solution Methods private void LoadSolutions() { //Check whether it already exists QueryExpression queryUnmanagedSolutions = new QueryExpression { EntityName = Solution.EntityLogicalName, ColumnSet = new ColumnSet(true), Criteria = new FilterExpression() }; queryUnmanagedSolutions.Criteria.AddCondition("ismanaged", ConditionOperator.Equal, false); EntityCollection querySolutionResults = _serviceProxy.RetrieveMultiple(queryUnmanagedSolutions); if (querySolutionResults.Entities.Count > 0) { //The Where() is important because a query for all solutions //where Type=Unmanaged returns 3 solutions. The CRM UI of a //vanilla instance shows only 1 unmanaged solution: "Default". //Assume "Active" and "Basic" should not be touched? UnmanagedSolutions = new ObservableCollection
( querySolutionResults.Entities .Select(x => x as Solution) .Where(s => s.UniqueName != "Active" && s.UniqueName != "Basic" ) ); //If only 1 solution returns just go ahead and default it. if (UnmanagedSolutions.Count == 1 && UnmanagedSolutions[0].UniqueName == "Default") { SelectedSolution = UnmanagedSolutions[0]; ActiveSolution = SelectedSolution; SetActivePublisher(); //Advance the user to the Packages TabItem TabControlSelectedIndex = 2; } else { //Advance the user to the Solutions TabItem TabControlSelectedIndex = 1; } OnPropertyChanged("UnmanagedSolutions"); OnPropertyChanged("SelectedSolution"); OnPropertyChanged("ActiveSolution"); } } private void InstantiateService() { try { if (SelectedConfiguration == null) throw new Exception("Please choose a configuration."); //Get the Password string password = String.Empty; PasswordWindow pw = new PasswordWindow(); pw.Owner = Application.Current.MainWindow; bool? submitted = pw.ShowDialog(); if (submitted.Value) { password = pw.GetPassword(); } else { ErrorWindow needPassword = new ErrorWindow("You need to supply a Password and Submit. Try again."); needPassword.Owner = Application.Current.MainWindow; needPassword.ShowDialog(); return; } _serverConnect = new ConsolelessServerConnection(); ConsolelessServerConnection.Configuration _config = new ConsolelessServerConnection.Configuration(); _config = _serverConnect.GetServerConfiguration( SelectedConfiguration.Attribute("server").Value, SelectedConfiguration.Attribute("orgName").Value, SelectedConfiguration.Attribute("userName").Value, password, SelectedConfiguration.Attribute("domain").Value); _serviceProxy = _serverConnect.GetOrganizationServiceProxy(_config.OrganizationUri,_config.EndpointType); // This statement is required to enable early-bound type support. _serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors .Add(new ProxyTypesBehavior()); // The OrganizationServiceContext is an object that wraps the service // proxy and allows creating/updating multiple records simultaneously. _orgContext = new OrganizationServiceContext(_serviceProxy); //Set the ActiveConnection ActiveConfiguration = SelectedConfiguration; //If all worked, retrieve the solutions. LoadSolutions(); } catch (Exception e) { StringBuilder sb = new StringBuilder(); sb.AppendLine(e.Message); sb.AppendLine(); sb.AppendLine("Please fix the Connection information and try again."); ErrorWindow errorWindow = new ErrorWindow(sb.ToString()); errorWindow.Owner = Application.Current.MainWindow; var x = errorWindow.ShowDialog(); } } private void ClearSolutions() { //Clear solutions UnmanagedSolutions.Clear(); SelectedSolution = null; ActiveSolution = null; ActivePublisher = null; } private void ActivateSelectedSolution() { if (SelectedSolution != null) { ActiveSolution = SelectedSolution; SetActivePublisher(); OnPropertyChanged("ActiveSolution"); //Advance the user to the Packages TabItem TabControlSelectedIndex = 2; } } private void SetActivePublisher() { if (ActiveSolution == null) return; var pub = from p in _orgContext.CreateQuery
() where p.PublisherId.Value == ActiveSolution.PublisherId.Id select new Publisher { CustomizationPrefix = p.CustomizationPrefix }; ActivePublisher = pub.First(); OnPropertyChanged("ActivePublisher"); } //Package Methods private void LoadPackages() { Packages.Clear(); var packages = XmlPackageData.Element("Packages").Descendants("Package"); foreach (var p in packages) { Packages.Add(p); } OnPropertyChanged("Packages"); } private void SavePackages() { //The user is influenced to believe a Save event will only //save the ActivePackage but really it will save all of them. //Code is in place to prevent the user from editing one package then //trying to load another without saving the first. //At this point the XmlRootData object is stale and needs to be //repopulated with the Packages collection. XmlPackageData.Descendants("Package").Remove(); //But the ActivePackage may have its Web Resources modified and they //need to be added back to the ActivePackage. if (ActivePackage != null) { ActivePackage.Elements("WebResourceInfo").Remove(); ActivePackage.Add(WebResourceInfos.ToArray()); } XmlPackageData.Element("Packages").Add(Packages.ToArray()); XmlPackageData.Save(PACKAGES_FILENAME); IsActivePackageDirty = false; } private void DeleteSelectedPackage() { if (SelectedPackage != null) { var toBeDeleted = Packages.Where(x => x == SelectedPackage).FirstOrDefault(); if (toBeDeleted != null) { if (ActivePackage == SelectedPackage) { ActivePackage = null; //Also, clear out any dependencies CurrentFiles.Clear(); CurrentFilesSelected.Clear(); WebResourceInfos.Clear(); WebResourceInfosSelected.Clear(); } Packages.Remove(toBeDeleted); SelectedPackage = null; } SavePackages(); } } private void ActivatePackage() { //Don't allow them to load a package without first saving //the ActivePackage if its dirty. if (ActivePackage != null && IsActivePackageDirty) { ErrorWindow dirtyPackageWindow = new ErrorWindow("You have unsaved changes to the Active Package. Please save before loading another package."); dirtyPackageWindow.Owner = Application.Current.MainWindow; dirtyPackageWindow.ShowDialog(); return; } if (SelectedPackage != null) { ActivePackage = SelectedPackage; //Readies the Files DataGrid SearchAndPopulateFiles(); //Readies the Web Resources DataGrid LoadWebResourceInfos(); } } private void CreateNewPackage() { if (ActivePackage != null) { SavePackages(); } XElement newPackage = new XElement("Package", new XAttribute("name", "NewPackage"), new XAttribute("rootPath", String.Empty), new XAttribute("isNamePrefix", true)); Packages.Add(newPackage); SelectedPackage = Packages[Packages.Count - 1]; ActivatePackage(); SavePackages(); } private void LoadWebResourceInfos() { if (ActivePackage == null) return; //As always, clear the collection first. WebResourceInfos.Clear(); WebResourceInfosSelected.Clear(); var webResourceInfos = ActivePackage.Elements("WebResourceInfo"); if (webResourceInfos != null) { foreach (var wr in webResourceInfos) { WebResourceInfos.Add(wr); } } } private void SearchAndPopulateFiles() { if (ActivePackage == null) return; string searchText = FileSearchText; //Find all files string rootPath = ActivePackage.Attribute("rootPath").Value; DiscoverFiles(rootPath, searchText); } //Misc private void ShowBrowseFolderDialog() { System.Windows.Forms.FolderBrowserDialog dlgWRFolder = new System.Windows.Forms.FolderBrowserDialog() { Description = "Select the folder containing the potential Web Resource files", ShowNewFolderButton = false }; if (dlgWRFolder.ShowDialog() == System.Windows.Forms.DialogResult.OK) { IsActivePackageDirty = false; //Because Web Resources are relative to the root path, //all the current Web ResourceInfos should be cleared WebResourceInfos.Clear(); WebResourceInfosSelected.Clear(); //Change the rootpath and notify all bindings ActivePackage.Attribute("rootPath").Value = dlgWRFolder.SelectedPath; OnPropertyChanged("ActivePackage"); //Auto-save SavePackages(); //Display new files SearchAndPopulateFiles(); } } private void DiscoverFiles(string rootPath, string searchText) { CurrentFiles.Clear(); CurrentFilesSelected.Clear(); if (rootPath != String.Empty) { DirectoryInfo di = new DirectoryInfo(rootPath); var files = di.EnumerateFiles("*", SearchOption.AllDirectories) .Where(f => ResourceExtensions.ValidExtensions.Contains(f.Extension)) .Where(f => f.Name != PACKAGES_FILENAME); if (!string.IsNullOrWhiteSpace(searchText)) { files = files.Where(f => f.FullName.Contains(searchText)); } foreach (FileInfo f in files) { CurrentFiles.Add(f); } OnPropertyChanged("CurrentFiles"); } } private void AddFilesToWebResources(object parameter) { //Set the ActivePackage as Dirty. IsActivePackageDirty = true; //Clear the collection of selected files CurrentFilesSelected.Clear(); //List
selectedFiles = new List
(); if (parameter != null && parameter is IEnumerable) { foreach (var fileInfo in (IEnumerable)parameter) { CurrentFilesSelected.Add((FileInfo)fileInfo); } } if (CurrentFilesSelected.Count > 0) { foreach (FileInfo fi in CurrentFilesSelected) { //Add it to the list of web resource info, if not already there. //The matching criteria will be the ? XElement newInfo = ConvertFileInfoToWebResourceInfo(fi); if (WebResourceInfos.Where(w => w.Attribute("filePath").Value == newInfo.Attribute("filePath").Value).Count() == 0) { WebResourceInfos.Add(newInfo); } else { //it's already in the list! do nothing. } } } } private void DeleteSelectedWebResources(object parameter) { //Set the ActivePackage as Dirty. IsActivePackageDirty = true; WebResourceInfosSelected.Clear(); if (parameter != null && parameter is IEnumerable) { //Lists allow the ForEach extension method good for //removing items of a collection. Looping through an //enumerable caused indexing errors after the first //iteration. List
infosToDelete = new List
(); foreach (var wr in (IEnumerable)parameter) { infosToDelete.Add((XElement)wr); } infosToDelete.ForEach(info => WebResourceInfos.Remove(info)); } } private XElement ConvertFileInfoToWebResourceInfo(FileInfo fi) { var x = fi.Extension.Split('.'); string type = x[x.Length - 1].ToLower(); String name = fi.FullName.Replace(ActivePackage.Attribute("rootPath").Value.Replace("/", "\\"), String.Empty); XElement newWebResourceInfo = new XElement("WebResourceInfo", new XAttribute("name", name.Replace("\\", "/")), new XAttribute("filePath", name), new XAttribute("displayName", fi.Name), new XAttribute("type", type), new XAttribute("description", String.Empty)); return newWebResourceInfo; } private void BeginUpload(object s, DoWorkEventArgs args) { //Retrieve all Web Resources so we can determine if each //needs be created or updated. var crmResources = RetrieveWebResourcesForActiveSolution(); //Create or Update the WebResource if (WebResourceInfosSelected.Count > 0) { _progressMessage.Clear(); AddMessage(String.Format("Processing {0} Web Resources...", WebResourceInfosSelected.Count.ToString())); int i = 1; foreach (XElement fi in WebResourceInfosSelected) { string name = GetWebResourceFullNameIncludingPrefix(fi); AddMessage(String.Empty); AddMessage(i.ToString() + ") " + name); if (IsWebResourceNameValid(name)) { //If the Unmanaged Solution already contains the Web Resource, //do an Update. var resourceThatMayExist = crmResources.Where(w => w.Name == name).FirstOrDefault(); if (resourceThatMayExist != null) { AddMessage("Already exists. Updating..."); UpdateWebResource(fi, resourceThatMayExist); AddMessage("Done."); } //If not, create the Web Resource and a Solution Component. else { AddMessage("Doesn't exist. Creating..."); CreateWebResource(fi); AddMessage("Done."); } } else { AddMessage(VALID_NAME_MSG); } i++; } AddMessage(String.Empty); AddMessage("Done processing files."); //All WebResources should be in. Publish all. if (ShouldPublishAllAfterUpload) { AddMessage(String.Empty); AddMessage("You chose to publish all customizations. Please be patient as it may take a few minutes to complete."); PublishAll(); } else if (ShouldPublishAllUploadedWebResource) { if (List_UploadedWebResources.Count > 0) { AddMessage(String.Empty); AddMessage("You chose to publish uploaded webresources. Please be patient as it may take a few minutes to complete."); PublishUploadedWebResource(); } } else { AddMessage(String.Empty); AddMessage("You chose not to publish all customizations."); } AddMessage("Process complete!"); } } List
List_UploadedWebResources; private void PublishUploadedWebResource() { try { AddMessage(String.Empty); AddMessage("Publishing uploaded..."); PublishXmlRequest publishRequest = new PublishXmlRequest(); StringBuilder sb = new StringBuilder(); foreach (Guid webresId in List_UploadedWebResources) { sb.Append("
" + webresId.ToString() + "
"); } publishRequest.ParameterXml = string.Format(@"
{0}
" , sb.ToString()); var response = (PublishXmlResponse)_serviceProxy.Execute(publishRequest); AddMessage("Done."); } catch (Exception e) { AddMessage("Error publishing: " + e.Message); } } private void UploadWebResources(object parameter) { IsOutputWindowDisplayed = true; AreAllButtonsEnabled = false; //Clear the collection of selected Web Resources WebResourceInfosSelected.Clear(); //Clear the collection of uploaded Web Resources List_UploadedWebResources.Clear(); if (parameter != null && parameter is IEnumerable) { foreach (var webResource in (IEnumerable)parameter) { WebResourceInfosSelected.Add((XElement)webResource); } } worker.RunWorkerAsync(WebResourceInfosSelected); } private void UploadAllWebResources() { UploadWebResources(WebResourceInfos); } private bool CanUploadWebResource() { if (ActiveConfiguration != null && ActiveSolution != null && ActivePublisher != null && ActivePackage != null) { return true; } return false; } private void PublishAll() { try { AddMessage(String.Empty); AddMessage("Publishing all customizations..."); PublishAllXmlRequest publishRequest = new PublishAllXmlRequest(); var response = (PublishAllXmlResponse)_serviceProxy.Execute(publishRequest); AddMessage("Done."); } catch (Exception e) { AddMessage("Error publishing: " + e.Message); } } private IEnumerable
RetrieveWebResourcesForActiveSolution() { //The following query finds all WebResources that are SolutionComponents for //the ActiveSolution. Simply querying WebResources does not retrieve the desired //results. Additionally, when creating WebResources, you must create a SolutionComponent //if attaching to any unmanaged solution other than the "Default Solution." var webResources = from wr in _orgContext.CreateQuery
() join sc in _orgContext.CreateQuery
() on wr.WebResourceId equals sc.ObjectId where wr.IsManaged == false where wr.IsCustomizable.Value == true where sc.ComponentType.Value == (int)componenttype.WebResource where sc.SolutionId.Id == ActiveSolution.SolutionId.Value select new WebResource { WebResourceType = wr.WebResourceType, WebResourceId = wr.WebResourceId, DisplayName = wr.DisplayName, Name = wr.Name, // Content = wr.Content, Removed to improve performance Description = wr.Description }; return webResources.AsEnumerable(); } private void CreateWebResource(XElement webResourceInfo) { try { //Create the Web Resource. WebResource wr = new WebResource() { Content = getEncodedFileContents(ActivePackage.Attribute("rootPath").Value + webResourceInfo.Attribute("filePath").Value), DisplayName = webResourceInfo.Attribute("displayName").Value, Description = webResourceInfo.Attribute("description").Value, LogicalName = WebResource.EntityLogicalName, Name = GetWebResourceFullNameIncludingPrefix(webResourceInfo) }; wr.WebResourceType = new OptionSetValue((int)ResourceExtensions.ConvertStringExtension(webResourceInfo.Attribute("type").Value)); //Special cases attributes for different web resource types. switch (wr.WebResourceType.Value) { case (int)ResourceExtensions.WebResourceType.Silverlight: wr.SilverlightVersion = "4.0"; break; } // ActivePublisher.CustomizationPrefix + "_/" + ActivePackage.Attribute("name").Value + webResourceInfo.Attribute("name").Value.Replace("\\", "/"), Guid theGuid = _serviceProxy.Create(wr); List_UploadedWebResources.Add(theGuid); //If not the "Default Solution", create a SolutionComponent to assure it gets //associated with the ActiveSolution. Web Resources are automatically added //as SolutionComponents to the Default Solution. if (ActiveSolution.UniqueName != "Default") { AddSolutionComponentRequest scRequest = new AddSolutionComponentRequest(); scRequest.ComponentType = (int)componenttype.WebResource; scRequest.SolutionUniqueName = ActiveSolution.UniqueName; scRequest.ComponentId = theGuid; var response = (AddSolutionComponentResponse)_serviceProxy.Execute(scRequest); } } catch (Exception e) { AddMessage("Error: " + e.Message); return; } } private void UpdateWebResource(XElement webResourceInfo, WebResource existingResource) { try { //These are the only 3 things that should (can) change. WebResource wr = new WebResource() { Content = getEncodedFileContents(ActivePackage.Attribute("rootPath").Value + webResourceInfo.Attribute("filePath").Value), DisplayName = webResourceInfo.Attribute("displayName").Value, Description = webResourceInfo.Attribute("description").Value }; wr.WebResourceId = existingResource.WebResourceId; _serviceProxy.Update(wr); List_UploadedWebResources.Add(existingResource.WebResourceId.Value); } catch (Exception e) { AddMessage("Error: " + e.Message); return; } } private string getEncodedFileContents(String pathToFile) { FileStream fs = new FileStream(pathToFile, FileMode.Open, FileAccess.Read); byte[] binaryData = new byte[fs.Length]; long bytesRead = fs.Read(binaryData, 0, (int)fs.Length); fs.Close(); #region Custom Modification return System.Convert.ToBase64String(binaryData, 0, binaryData.Length); //byte[] convertedBytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding("GB2312"), binaryData); //return System.Convert.ToBase64String(convertedBytes, 0, convertedBytes.Length); #endregion } private string GetWebResourceFullNameIncludingPrefix(XElement webResourceInfo) { //The Web Resource name always starts with the Publisher's Prefix //i.e., "new_" string name = ActivePublisher.CustomizationPrefix + "_"; //Check to see if the user has chosen to add the Package Name as part of the //prefix. if (!String.IsNullOrWhiteSpace(ActivePackage.Attribute("isNamePrefix").Value) && Boolean.Parse(ActivePackage.Attribute("isNamePrefix").Value) == true) { name += "/" + ActivePackage.Attribute("name").Value; } //Finally add the name on to the prefix name += webResourceInfo.Attribute("name").Value; return name; } private bool IsWebResourceNameValid(string name) { Regex inValidWRNameRegex = new Regex("[^a-z0-9A-Z_\\./]|[/]{2,}", (RegexOptions.Compiled | RegexOptions.CultureInvariant)); bool result = true; //Test valid characters if (inValidWRNameRegex.IsMatch(name)) { AddMessage(VALID_NAME_MSG); result = false; } //Test length //Remove the customization prefix and leading _ if (name.Remove(0, ActivePublisher.CustomizationPrefix.Length + 1).Length > 100) { AddMessage("ERROR: Web Resource name must be <= 100 characters."); result = false; } return result; } private void AddMessage(string msg) { //Assures that this happens on the UI thread this.BeginInvoke(() => { ProgressMessage = msg; }); } #endregion }}

  WebResourceView.xaml

1 
11 12
13
14
15
16
17
18
19
20
21
22
23
24
25 26
31
32 33
37 38
39
40
47
48
49
50
51
52
53 54
55
58
62 63
64
65
66 67 68
69
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 92
93
98
99
100
101
102
103
104
105
106
107
112
120 121 122 123
124
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 144
145 146
151 152
160 161
171
172
173
174
175
176
177 178 179 180
191 192
199
200
201 202
203
207
208
209
210
211
212
213
214
215
216 217
218
219
220
221
222 223
227 228
229
Web Resource name prefix:
230
232
234
236
238 239
240 241 242
249
250
251
252
253
254
255
256 257
262 263
264
265 266
267
271 272
276 277
278
284
290
296
303
308
309 310
311
314
315
316
317
318
319
320
324
325
326
327
328
329
330 331 332
333
334 335

 

转载于:https://www.cnblogs.com/tcli/p/7154792.html

你可能感兴趣的文章
转:Vue keep-alive实践总结
查看>>
深入python的set和dict
查看>>
C++ 11 lambda
查看>>
Android JSON数据解析
查看>>
DEV实现日期时间效果
查看>>
java注解【转】
查看>>
centos 下安装g++
查看>>
嵌入式,代码调试----GDB扫盲
查看>>
下一步工作分配
查看>>
Response. AppendHeader使用大全及文件下载.net函数使用注意点(转载)
查看>>
Wait Functions
查看>>
jQuery最佳实践
查看>>
centos64i386下apache 403没有权限访问。
查看>>
jquery用法大全
查看>>
PC-BSD 9.2 发布,基于 FreeBSD 9.2
查看>>
css斜线
查看>>
Windows phone 8 学习笔记(3) 通信
查看>>
Revit API找到风管穿过的墙(当前文档和链接文档)
查看>>
Scroll Depth – 衡量页面滚动的 Google 分析插件
查看>>
Windows 8.1 应用再出发 - 视图状态的更新
查看>>