diff --git a/.gitignore b/.gitignore
index 401ae9a6..819cf615 100644
--- a/.gitignore
+++ b/.gitignore
@@ -139,3 +139,4 @@ UpgradeLog*.XML
*.ide-shm
*.ide-wal
/.vs
+/spkl/.vs/spkl
diff --git a/spkl/CrmSvcUtilFilteringService/CrmSvcUtil.FilteringService.csproj b/spkl/CrmSvcUtilFilteringService/CrmSvcUtil.FilteringService.csproj
index 6225a625..4c4e5be2 100644
--- a/spkl/CrmSvcUtilFilteringService/CrmSvcUtil.FilteringService.csproj
+++ b/spkl/CrmSvcUtilFilteringService/CrmSvcUtil.FilteringService.csproj
@@ -52,48 +52,66 @@
..\packages\Microsoft.CrmSdk.CoreTools.9.0.0.7\content\bin\coretools\CrmSvcUtil.exe
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Crm.Sdk.Proxy.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.21\lib\net462\Microsoft.Crm.Sdk.Proxy.dll
-
- False
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
- True
+
+
+ ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
-
- False
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.25\lib\net462\Microsoft.Rest.ClientRuntime.dll
True
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.21\lib\net462\Microsoft.Xrm.Sdk.dll
- ..\packages\Microsoft.CrmSdk.Deployment.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll
- True
+ ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.21\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll
- ..\packages\Microsoft.CrmSdk.Workflow.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll
+ ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.21\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll
-
- ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.0.7\lib\net452\Microsoft.Xrm.Tooling.Connector.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.25\lib\net462\Microsoft.Xrm.Tooling.Connector.dll
True
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+
+
-
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
+
+
@@ -108,7 +126,7 @@
-
+
PreserveNewest
Designer
@@ -120,16 +138,23 @@
+
-
+
+
+
-
+
+
+
+
+
diff --git a/spkl/CrmSvcUtilFilteringService/app.config b/spkl/CrmSvcUtilFilteringService/app.config
index eb4fca6a..dc96ecaa 100644
--- a/spkl/CrmSvcUtilFilteringService/app.config
+++ b/spkl/CrmSvcUtilFilteringService/app.config
@@ -14,6 +14,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe
new file mode 100644
index 00000000..7c583880
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe.config b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe.config
new file mode 100644
index 00000000..ddcb24e8
--- /dev/null
+++ b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.exe.config
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.xml b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.xml
new file mode 100644
index 00000000..c933aa16
--- /dev/null
+++ b/spkl/CrmSvcUtilFilteringService/bin/coretools/CrmSvcUtil.xml
@@ -0,0 +1,1428 @@
+
+
+
+ CrmSvcUtil
+
+
+
+
+ Used to raise the interactive dialog to login.
+
+
+
+
+ Used to create a connection utilizing a passed in connection string.
+
+
+
+
+ Used to login via OAuth to CRM Online, Hidden for initial ship... but here to allow for complex auth situations.
+
+
+
+
+ Hidden... Used by devToolkit to set the Connection profile to use for this call.
+
+
+
+
+ Hidden... Used by the devToolkit to set the appName whos connection is being used.
+
+
+
+
+ Type of command line argument represented.
+
+
+
+
+ Argument is optional.
+
+
+
+
+ Argument is required.
+
+
+
+
+ The argument may appear multiple times.
+
+
+
+
+ Argument is a binary argument. If it shows up
+ it is equivalent to a true value.
+
+
+
+
+ Argument is hidden from the user. It can be supplied
+ on the command line, but will not show up in the
+ standard usage message.
+
+
+
+
+ Wrapper class for Command Line Argument PropertyInfos.
+
+
+
+
+ Character used to start a new command line paramter.
+
+
+
+
+ Character used to seperate command line parameter and value.
+
+
+
+
+ Format to use when constructing the short form description for an argument.
+
+
+
+
+ Represents a command line argument.
+
+
+
+
+ Creates a new command line argument attribute.
+
+ Type of argument represented by the property.
+ Switch used by the command line argument
+
+
+
+ Type of command line argument
+
+
+
+
+ Switch used to represent the argument.
+
+
+
+
+ Shortcut switch used to represent the argument.
+
+
+
+
+ Description of the command line argument.
+
+
+
+
+ Description of the parameter.
+
+
+
+
+ Utility class to parse command line arguments.
+
+
+
+
+ The object that contains the properties to set.
+
+
+
+
+ A mapping of argument switches to command line arguments.
+
+
+
+
+ A list of all of the arguments that are supported
+
+
+
+
+ Creates a new command line parser for the given object.
+
+ The object containing the properties representing the command line args to set.
+
+
+
+ Populates the command line arguments map.
+
+
+
+
+ Interface for IOrganization metadata
+
+
+
+
+ Array of complete EntityMetadata for the Organization.
+
+
+
+
+ Array of complete OptionSetMetadata for the Organization.
+
+
+
+
+ All SdkMessages for the Organization.
+
+
+
+
+ SDK Message result
+
+
+
+
+ Default constructor
+
+
+
+
+ Message name
+
+
+
+
+ Gets or sets whether the message is private
+
+
+
+
+ Gets or sets the customization level
+
+
+
+
+ Gets or sets the message id
+
+
+
+
+ Gets or sets the message pair id
+
+
+
+
+ Gets or sets the message pair namespace
+
+
+
+
+ Gets or sets the message request id
+
+
+
+
+ Gets or sets the message request name
+
+
+
+
+ Gets or sets the message request field name
+
+
+
+
+ Gets or sets whether the message request field is optional
+
+
+
+
+ Gets or sets the message request field parser
+
+
+
+
+ Gets or sets the message request field CLR parser
+
+
+
+
+ Gets or sets the message request response id
+
+
+
+
+ Gets or sets the message request response field value
+
+
+
+
+ Gets or sets the message request response field formatter
+
+
+
+
+ Gets or sets the message request response field CLR formatter
+
+
+
+
+ Gets or sets the message request response field name
+
+
+
+
+ Gets or sets the message request field position
+
+
+
+
+ Gets or sets the message response field position
+
+
+
+
+ Gets or sets the message filter id
+
+
+
+
+ Gets or sets the message primary OTC filter
+
+
+
+
+ Gets or sets the message secondary OTC filter
+
+
+
+
+ Set of SDK message results
+
+
+
+
+ Default constructor
+
+
+
+
+ Gets or sets an array of results
+
+
+
+
+ Gets or sets the paging cookie
+
+
+
+
+ Gets or sets a flag for more records
+
+
+
+
+ An SDK Message
+
+
+
+
+ Default constructor
+
+
+
+
+ Gets the SDK message name
+
+
+
+
+ Gets the SDK message id
+
+
+
+
+ Gets whether the SDK message is private
+
+
+
+
+ Gets whether the SDK message is a custom action
+
+
+
+
+ Gets a dictionary of message pairs
+
+
+
+
+ Gets a dictionary of message filters
+
+
+
+
+ Fills an SDK message from a given result
+
+
+
+
+ An SDK message filter
+
+
+
+
+ Constructor
+
+ Message filter id
+
+
+
+ Constructor
+
+ Message filter id
+ Primary object type code
+ Secondary object type code
+ Whether the message filter is visible
+
+
+
+ Gets the message filter id
+
+
+
+
+ Gets or sets the message filter primary object type code
+
+
+
+
+ Gets or sets the message secondary object type code
+
+
+
+
+ Gets or sets whether the message filter is visible
+
+
+
+
+ An SDK message pair
+
+
+
+
+ Constructor
+
+ SDK message
+ Message pair id
+ Message namespace
+
+
+
+ Gets the message pair id
+
+
+
+
+ Gets the message namespace
+
+
+
+
+ Gets or sets the message
+
+
+
+
+ Gets or sets the message request
+
+
+
+
+ Gets or sets the message response
+
+
+
+
+ An SDK message request
+
+
+
+
+ Constructor
+
+ SDK Message
+ Message request id
+ Message request name
+
+
+
+ Gets the message request id
+
+
+
+
+ Gets the message pair of the request
+
+
+
+
+ Gets the message request name
+
+
+
+
+ Gets a dictionary of message request fields
+
+
+
+
+ An SDK message request field
+
+
+
+
+ Constructor
+
+ SDK message request
+ Request field index
+ Request field name
+ Request field CLR formatter
+ Whether the request field is optional
+
+
+
+ Gets the SDK message request
+
+
+
+
+ Gets the message request field index
+
+
+
+
+ Gets the message request field name
+
+
+
+
+ Gets the message request field CLR formatter
+
+
+
+
+ Gets whether the message field is optional
+
+
+
+
+ Gets whether the message request field is generic
+
+
+
+
+ An SDK message response
+
+
+
+
+ Constructor
+
+ Message response id
+
+
+
+ Gets the message response id
+
+
+
+
+ Gets the message response fields
+
+
+
+
+ An SDK message response field
+
+
+
+
+ Constructor
+
+ Field index
+ Field name
+ Field CLR formatter
+ Field value
+
+
+
+ Gets the message response field index
+
+
+
+
+ Gets the message response field name
+
+
+
+
+ Gets the message response field CLR formatter
+
+
+
+
+ Gets the message response field value
+
+
+
+
+ SDK Messages
+
+
+
+
+ Constructor
+
+ SDK message collection
+
+
+
+ Gets the message collection
+
+
+
+
+ Gets the MessagePagingInfo for a given collection SDK messages
+
+
+
+
+ Message paging info
+
+
+
+
+ Gets or sets the paging cookie
+
+
+
+
+ Gets or sets whether the paging info has more records
+
+
+
+
+ Gets the message paging info from a set of message results
+
+
+
+
+ If true a child attribute cannot be published or externally consumed.
+
+
+
+
+ Management utility for the Device Id
+
+
+
+
+ Loads the device credentials (if they exist). If they don't
+
+ Application id
+ URL for the current token issuer
+
+ The issuerUri can be retrieved from the IServiceConfiguration interface's CurrentIssuer property.
+
+
+
+
+ Registers the given device with Live ID
+
+ ID for the application
+ URL for the current token issuer
+ ClientCredentials that were registered
+
+ The issuerUri can be retrieved from the IServiceConfiguration interface's CurrentIssuer property.
+
+
+
+
+ Registers the given device with Live ID
+
+ ID for the application
+ URL for the current token issuer
+ Device name that should be registered
+ Device password that should be registered
+ ClientCredentials that were registered
+
+ The issuerUri can be retrieved from the IServiceConfiguration interface's CurrentIssuer property.
+
+
+
+
+ Loads the device's credentials from the file system
+
+ URL for the current token issuer
+ Device Credentials (if set) or null
+
+ The issuerUri can be retrieved from the IServiceConfiguration interface's CurrentIssuer property.
+
+
+
+
+ Indicates an error during registration
+
+
+
+
+ Unspecified or Unknown Error occurred
+
+
+
+
+ Interface Disabled
+
+
+
+
+ Invalid Request Format
+
+
+
+
+ Unknown Client Version
+
+
+
+
+ Blank Password
+
+
+
+
+ Missing Device User Name or Password
+
+
+
+
+ Invalid Parameter Syntax
+
+
+
+
+ Internal Error
+
+
+
+
+ Device Already Exists
+
+
+
+
+ Indicates that Device Registration failed
+
+
+
+
+ Construct an instance of the DeviceRegistrationFailedException class
+
+
+
+
+ Construct an instance of the DeviceRegistrationFailedException class
+
+ Error code that occurred
+ Subcode that occurred
+
+
+
+ Construct an instance of the DeviceRegistrationFailedException class
+
+ Error code that occurred
+ Subcode that occurred
+ Inner exception
+
+
+
+ Construct an instance of the DeviceRegistrationFailedException class
+
+
+
+
+
+
+ Device requestration request
+
+
+
+
+ Default constructor
+
+
+
+
+ Constructor
+
+ Application id
+ Device to register
+
+
+
+ Gets or sets the device registration client info
+
+
+
+
+ Gets or sets the device registration authentication
+
+
+
+
+ Device registration client info
+
+
+
+
+ Gets or sets the device registration client info's application id
+
+
+
+
+ Gets or sets the device registration client info version
+
+
+
+
+ Device registration authentication
+
+
+
+
+ Gets or sets the device registration authentication member name
+
+
+
+
+ Gets or sets the device registration authentication password
+
+
+
+
+ Device registration response
+
+
+
+
+ Gets or sets whether the device registration was successful
+
+
+
+
+ Gets or sets the device registration puid
+
+
+
+
+ Gets or sets the device registration error
+
+
+
+
+ Gets or sets the device registration error sub code
+
+
+
+
+ Device registration response error
+
+
+
+
+ Gets or sets the device registration error code
+
+
+
+
+ Live device
+
+
+
+
+ Gets or sets the device version
+
+
+
+
+ Gets or sets the device user name
+
+
+
+
+ Gets or sets the device token
+
+
+
+
+ Gets or sets the device token expiry
+
+
+
+
+ Gets or sets the device clock skew
+
+
+
+
+ Device user name
+
+
+
+
+ Default constructor
+
+
+
+
+ Gets or sets the device user name
+
+
+
+
+ Gets or sets the device user type
+
+
+
+
+ Gets or sets the device user password
+
+
+
+
+ Gets or sets the device id
+
+
+
+
+ Gets or sets the device user's decrypted password
+
+
+
+
+ Creates client credentials for the device user
+
+ An instance of ClientCredentials
+
+
+
+ Interface for metadata provider query service
+
+
+
+
+ Retrieves entities for the given service
+
+ Service to query
+ An EntityMetadata array
+
+
+
+ Retrieves option sets for the given service
+
+ Service to query
+ An OptionSetMetadataBase array
+
+
+
+ Retrieves SDK requests for the given service
+
+ Service to query
+ SdkMessages
+
+
+
+ Special class to hold hardcoded entity and attribute name mappings.
+
+
+
+
+ Retrieves a name for the Entity being generated.
+
+
+
+
+ Static constructor.
+
+
+
+
+ Updates the timeout value to extend the amount of item that a request will wait.
+
+
+
+
+ Builds a connection string from the passed in parameters.
+
+
+
+
+
+ Type of code to generate
+
+
+
+
+ Type Class
+
+
+
+
+ Type Enum
+
+
+
+
+ Type Field
+
+
+
+
+ Type Method
+
+
+
+
+ Type Property
+
+
+
+
+ Type Struct
+
+
+
+
+ Type Parameter
+
+
+
+
+ Interface that provides the ability to generate code based on organization metadata.
+
+
+
+
+ Writes code based on the organization metadata.
+
+ Organization metadata to generate the code for.
+ Laguage to generate
+ Output file to write the generated code to.
+ Target namespace for the generated code.
+ ServiceProvider to query for additional services that can be used during code generation.
+
+
+
+ Returns the type that gets generated for the OptionSetMetadata
+
+
+
+
+ Returns the type that gets generated for the Option
+
+
+
+
+ Returns the type that gets generated for the EntityMetadata
+
+
+
+
+ Returns the type that gets generated for the AttributeMetadata
+
+
+
+
+ Returns the type that gets generated for the SdkMessagePair
+
+
+
+
+ Returns the type that gets generated for the SdkMessageRequestField
+
+
+
+
+ Returns the type that gets generated for the SdkMessageResponseField
+
+
+
+
+ Interface that can be used to filter out specific pieces of metadata from having code generated for it.
+
+
+
+
+ Returns true to generate code for the OptionSet and false otherwise.
+
+
+
+
+ Returns true to generate code for the Option and false otherwise.
+
+
+
+
+ Returns true to generate code for the Entity and false otherwise.
+
+
+
+
+ Returns true to generate code for the Attribute and false otherwise.
+
+
+
+
+ Returns true to generate code for the 1:N, N:N, or N:1 relationship and false otherwise.
+
+
+
+
+ Returns true to generate code for the data context and false otherwise.
+
+
+
+
+ Interface for code writer message filter service
+
+
+
+
+ Returns true to generate code for the SDK Message and false otherwise.
+
+
+
+
+ Returns true to generate code for the SDK Message Pair and false otherwise.
+
+
+
+
+ Interface that can be used to customize the CodeDom before it generates code.
+
+
+
+
+ Customize the generated types before code is generated
+
+
+
+
+ Interface that provides metadata for a given organization.
+
+
+
+
+ Returns the metadata for a given organization. Subsequent calls to the method should
+ return the same set of information on the IOrganizationMetadata object.
+
+
+
+
+ Interface that provides metadata for a given organization.
+
+
+
+
+ Loads metadata for the given service
+
+ Service to query
+ IOrganizationMetadata
+
+
+
+ Used by the ICodeGenerationService to retrieve names for the CodeDOM objects being created.
+
+
+
+
+ Returns a name for the OptionSet being generated.
+
+
+
+
+ Retrieves a name for the Option being generated.
+
+
+
+
+ Retrieves a name for the Entity being generated.
+
+
+
+
+ Retrieves a name for the Attribute being generated.
+
+
+
+
+ Retrieves a name for the 1:N, N:N, or N:1 relationship being generated.
+
+
+
+
+ Retrieves a name for the data context being generated.
+
+
+
+
+ Retrieves a name for a set of entities.
+
+
+
+
+ Retrieves a name for the MessagePair being generated.
+
+
+
+
+ Retrieves a name for the Request Field being generated.
+
+
+
+
+ Retrieves a name for the Response Field being generated.
+
+
+
+
+ Used by the ICodeGenerationService to retrieve types for the CodeDOM objects being created.
+
+
+
+
+ Retrieves a CodeTypeReference for the entity set being generated.
+
+
+
+
+ Retrieves a CodeTypeReference for the attribute being generated.
+
+
+
+
+ Retrieves a CodeTypeReference for the 1:N, N:N, or N:1 relationship being generated.
+
+
+
+
+ Retrieves a CodeTypeReference for the Request Field being generated.
+
+
+
+
+ Retrieves a CodeTypeReference for the Response Field being generated.
+
+
+
+
+ Trace Logger for this project
+
+
+
+
+ Trace Tag.
+
+
+
+
+ String Builder Info.
+
+
+
+
+ Last Exception.
+
+
+
+
+ Last Error from CRM.
+
+
+
+
+ Last Exception from CRM .
+
+
+
+
+ Returns the trace source level for the current logger.
+
+
+
+
+ Constructor.
+
+ trace source name
+
+
+
+ Last error reset.
+
+
+
+
+ Log a Message.
+
+
+
+
+
+ Log a Trace event.
+
+
+
+
+
+
+ Log a Trace event.
+
+ Error Message
+ Trace Event type Information
+ Exception object
+
+
+
+ Log an error with an Exception.
+
+
+
+
+
+ Logs the error text to the stream.
+
+ Exception to be written.
+ Stream writer to use to write the exception.
+ level of the exception, this deals with inner exceptions.
+
+
+
+ Interaction logic for CRMInteractiveLogin.xaml
+
+
+ CRMInteractiveLogin
+
+
+
+
+ Microsoft.Xrm.Tooling.Connector services
+
+
+
+
+ Bool flag to determine if there is a connection
+
+
+
+
+ CRM Connection Manager component.
+
+
+
+
+ This is used to allow the UI to reset w/out closing
+
+
+
+
+ CRM Connection Manager
+
+
+
+
+ Host Name to use..
+
+
+
+
+ Profile Name to use
+
+
+
+
+ When set to true, forces a user login,
+
+
+
+
+ Raised when a connection to CRM has completed.
+
+
+
+
+ Default constructor
+
+
+
+
+ Raised when the window loads for the first time.
+
+
+
+
+
+
+ Run Login process.
+
+
+
+
+ Updates from the Auto Login process.
+
+
+
+
+
+
+ Complete Event from the Auto Login process
+
+
+
+
+
+
+ Login control connect check starting.
+
+
+
+
+
+
+ Login control connect check status event.
+
+
+
+
+
+
+ Login control Error event.
+
+
+
+
+
+
+ Login Control Cancel event raised.
+
+
+
+
+
+
+ This raises and processes Success
+
+
+
+
+ InitializeComponent
+
+
+
+
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.ApplicationInsights.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.ApplicationInsights.dll
new file mode 100644
index 00000000..7d401e9f
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.ApplicationInsights.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Crm.Sdk.Proxy.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Crm.Sdk.Proxy.dll
new file mode 100644
index 00000000..9f07230b
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Crm.Sdk.Proxy.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.IdentityModel.Clients.ActiveDirectory.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.IdentityModel.Clients.ActiveDirectory.dll
new file mode 100644
index 00000000..4f408cf0
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.IdentityModel.Clients.ActiveDirectory.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetry.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetry.dll
new file mode 100644
index 00000000..634b57bf
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetry.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetryChannel.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetryChannel.dll
new file mode 100644
index 00000000..7d53d81f
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.PowerApps.AppInsights.BatchedTelemetryChannel.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Rest.ClientRuntime.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Rest.ClientRuntime.dll
new file mode 100644
index 00000000..6dc62c71
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Rest.ClientRuntime.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.Deployment.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.Deployment.dll
new file mode 100644
index 00000000..07107767
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.Deployment.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.dll
new file mode 100644
index 00000000..b803c938
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Sdk.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Connector.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Connector.dll
new file mode 100644
index 00000000..85d6b31f
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Connector.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.CrmConnectControl.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.CrmConnectControl.dll
new file mode 100644
index 00000000..fb5e8519
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.CrmConnectControl.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Ui.Styles.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Ui.Styles.dll
new file mode 100644
index 00000000..d6286822
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Microsoft.Xrm.Tooling.Ui.Styles.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/Newtonsoft.Json.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/Newtonsoft.Json.dll
new file mode 100644
index 00000000..b1a0fa9b
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/Newtonsoft.Json.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe
new file mode 100644
index 00000000..b966f5bb
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe.config b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe.config
new file mode 100644
index 00000000..4b54542b
--- /dev/null
+++ b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackager.exe.config
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackagerLib.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackagerLib.dll
new file mode 100644
index 00000000..24e50d4d
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/SolutionPackagerLib.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/System.Diagnostics.DiagnosticSource.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/System.Diagnostics.DiagnosticSource.dll
new file mode 100644
index 00000000..c35584d9
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/System.Diagnostics.DiagnosticSource.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/System.ValueTuple.dll b/spkl/CrmSvcUtilFilteringService/bin/coretools/System.ValueTuple.dll
new file mode 100644
index 00000000..1cadbf3e
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/System.ValueTuple.dll differ
diff --git a/spkl/CrmSvcUtilFilteringService/bin/coretools/pacTelemetryUpload.exe b/spkl/CrmSvcUtilFilteringService/bin/coretools/pacTelemetryUpload.exe
new file mode 100644
index 00000000..c7d380da
Binary files /dev/null and b/spkl/CrmSvcUtilFilteringService/bin/coretools/pacTelemetryUpload.exe differ
diff --git a/spkl/CrmSvcUtilFilteringService/packages.config b/spkl/CrmSvcUtilFilteringService/packages.config
index fd1bfa31..c0adb684 100644
--- a/spkl/CrmSvcUtilFilteringService/packages.config
+++ b/spkl/CrmSvcUtilFilteringService/packages.config
@@ -1,10 +1,15 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks.Tests/DeployPluginAndWorkflowTests.cs b/spkl/SparkleXrm.Tasks.Tests/DeployPluginAndWorkflowTests.cs
new file mode 100644
index 00000000..e125d244
--- /dev/null
+++ b/spkl/SparkleXrm.Tasks.Tests/DeployPluginAndWorkflowTests.cs
@@ -0,0 +1,125 @@
+using FakeItEasy;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Microsoft.Xrm.Sdk;
+using Microsoft.Xrm.Sdk.Messages;
+using Microsoft.Xrm.Tooling.Connector;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SparkleXrm.Tasks.Tests
+{
+ [TestClass]
+ public class DeployPluginAndWorkflowTests
+ {
+ [TestMethod]
+ [TestCategory("Integration Tests")]
+ public void DeployPlugins()
+ {
+ CrmServiceClient crmSvc = new CrmServiceClient(ConfigurationManager.ConnectionStrings["integration_testing"].ConnectionString);
+ var userId = crmSvc.GetMyCrmUserId();
+ var trace = new TraceLogger();
+ var pluginTask = new DeployPluginsTask(crmSvc, trace);
+ var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
+ @"..\..\..\TestPluginWorkflowCombined");
+
+ pluginTask.Execute(path);
+ }
+
+ [TestMethod]
+ [TestCategory("Integration Tests")]
+ public void DeployWorfklows()
+ {
+ CrmServiceClient crmSvc = new CrmServiceClient(ConfigurationManager.ConnectionStrings["integration_testing"].ConnectionString);
+ var userId = crmSvc.GetMyCrmUserId();
+ var trace = new TraceLogger();
+ var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
+ @"..\..\..\TestPluginWorkflowCombined");
+
+ var wfTask = new DeployWorkflowActivitiesTask(crmSvc, trace);
+
+ wfTask.Execute(path);
+ }
+
+ [TestMethod]
+ [TestCategory("Unit Tests")]
+ public void DeployPluginsUnChangedActivities()
+ {
+ var fakeService = A.Fake(a => a.Strict());
+
+ var trace = new TraceLogger();
+ var task = new DeployPluginsTask(fakeService, trace);
+ var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
+ @"..\..\..\TestPluginWorkflowCombined");
+
+ //var messageRequestBuilder = A.Fake();
+
+ var plugin = new PluginAssembly()
+ {
+ Id = Guid.NewGuid()
+ };
+
+ var pluginTypeToBeRemoved = new PluginType
+ {
+ Id = Guid.NewGuid(),
+ Name = "Type",
+ PluginAssemblyId = plugin.ToEntityReference(),
+ TypeName = "TypeName",
+ IsWorkflowActivity = false
+ };
+
+ var existingWFActivityNotToBeRemoved = new PluginType
+ {
+ Id = Guid.NewGuid(),
+ Name = "Type",
+ PluginAssemblyId = plugin.ToEntityReference(),
+ TypeName = "WFActivity",
+ IsWorkflowActivity = true
+ };
+
+ A.CallTo(() => fakeService.Execute(A.Ignored)).ReturnsLazily((a) =>
+ {
+ var response = new RetrieveMultipleResponse();
+ var logicalName = ((a.Arguments[0] as RetrieveMultipleRequest).Query as Microsoft.Xrm.Sdk.Query.QueryExpression).EntityName;
+ switch (logicalName)
+ {
+ case PluginAssembly.EntityLogicalName:
+ response["EntityCollection"] = new EntityCollection(new[] { plugin });
+ break;
+
+ case PluginType.EntityLogicalName:
+ response["EntityCollection"] = new EntityCollection(new[] { pluginTypeToBeRemoved, existingWFActivityNotToBeRemoved });
+ break;
+
+ case SdkMessageProcessingStepImage.EntityLogicalName:
+ case SdkMessageProcessingStep.EntityLogicalName:
+ response["EntityCollection"] = new EntityCollection();
+ break;
+
+ case SdkMessageFilter.EntityLogicalName:
+ response["EntityCollection"] = new EntityCollection(new[] { new SdkMessageFilter(){
+ SdkMessageFilterId = Guid.NewGuid(),
+ SdkMessageId = new EntityReference(SdkMessage.EntityLogicalName,Guid.NewGuid())
+ } });
+ break;
+ }
+
+ return response;
+ });
+
+ A.CallTo(() => fakeService.Update(A.Ignored)).DoesNothing();
+ A.CallTo(() => fakeService.Create(A.Ignored)).ReturnsLazily((a) =>
+ {
+ return Guid.NewGuid();
+ });
+ A.CallTo(() => fakeService.Delete(
+ A.That.Matches(a => a == PluginType.EntityLogicalName),
+ A.That.Matches(a => a == pluginTypeToBeRemoved.Id))).DoesNothing();
+ task.Execute(path);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks.Tests/DeployPluginTests.cs b/spkl/SparkleXrm.Tasks.Tests/DeployPluginTests.cs
index f42e53be..06c4b39c 100644
--- a/spkl/SparkleXrm.Tasks.Tests/DeployPluginTests.cs
+++ b/spkl/SparkleXrm.Tasks.Tests/DeployPluginTests.cs
@@ -42,8 +42,8 @@ public void DeployWorkflowActivities()
@"..\..\..\TestWorkflowActivity");
task.Execute(path);
-
}
+
[TestMethod]
[TestCategory("Unit Tests")]
public void TestGetWorkflowActivityMetadata()
@@ -59,15 +59,15 @@ public void TestGetWorkflowActivityMetadata()
var assemblyPath = new DirectoryService().SimpleSearch(testAssemblyPathRoot, "TestWorkflowActivity.dll");
- Assembly thisAssembly = Reflection.ReflectionOnlyLoadAssembly(assemblyPath);
+ Assembly thisAssembly = Reflection.LoadAssembly(assemblyPath);
IEnumerable pluginTypes = Reflection.GetTypesInheritingFrom(thisAssembly, typeof(System.Activities.CodeActivity));
var workflowActivityCustomBaseClass = Reflection.GetAttributes(pluginTypes.Where(t => t.Name == "WorkflowActivityInheritingFromWorkflowActivityBase"), typeof(CrmPluginRegistrationAttribute).Name);
- Assert.AreEqual(1, workflowActivityCustomBaseClass.Count(),"Custom Base Class Metadata");
+ Assert.AreEqual(1, workflowActivityCustomBaseClass.Count(), "Custom Base Class Metadata");
var codeActivityBaseClass = Reflection.GetAttributes(pluginTypes.Where(t => t.Name == "WorkflowActivity"), typeof(CrmPluginRegistrationAttribute).Name);
Assert.AreEqual(1, codeActivityBaseClass.Count(), "CodeActiviy Base Class Metadata");
-
}
+
[TestMethod]
[TestCategory("Unit Tests")]
public void TestGetPluginMetadata()
@@ -83,7 +83,7 @@ public void TestGetPluginMetadata()
var assemblyPath = new DirectoryService().SimpleSearch(testAssemblyPathRoot, "TestPlugin.dll");
- Assembly thisAssembly = Reflection.ReflectionOnlyLoadAssembly(assemblyPath);
+ Assembly thisAssembly = Reflection.LoadAssembly(assemblyPath);
IEnumerable pluginTypes = Reflection.GetTypesImplementingInterface(thisAssembly, typeof(Microsoft.Xrm.Sdk.IPlugin));
var attributes = Reflection.GetAttributes(pluginTypes.Where(t => t.Name == "PreValidateaccountUpdate"), typeof(CrmPluginRegistrationAttribute).Name);
var pluginStep = (CrmPluginRegistrationAttribute)attributes.Where(s => s.ConstructorArguments[5].Value.ToString() == "Create Step").First().CreateFromData();
@@ -97,8 +97,7 @@ public void DuplicatePluginNameOnDownload()
{
// Since the name is used to uniquely identify plugins per type, we can't have existing duplicates when downloading steps
-
- // Arrange
+ // Arrange
ServiceLocator.Init();
var trace = new TraceLogger();
@@ -122,7 +121,6 @@ public void DuplicatePluginNameOnDownload()
Name = "step"
}
};
-
});
var task = new DownloadPluginMetadataTask(ctx, trace);
@@ -138,23 +136,17 @@ public void DuplicatePluginNameOnDownload()
}
catch (SparkleTaskException ex)
{
-
exception = (ex.ExceptionType == SparkleTaskException.ExceptionTypes.DUPLICATE_STEP);
-
}
// Assert
Assert.IsTrue(exception, "Duplicate step names not detected");
-
-
-
}
[TestMethod]
[TestCategory("Unit Tests")]
public void DuplicatePluginNameOnDeploy()
{
-
// Assemble
List testType = new List()
{
@@ -169,13 +161,10 @@ public void DuplicatePluginNameOnDeploy()
}
catch (SparkleTaskException ex)
{
-
exception = (ex.ExceptionType == SparkleTaskException.ExceptionTypes.DUPLICATE_STEP);
-
}
// Assert
Assert.IsTrue(exception, "Duplicate step names not detected");
-
}
[TestMethod]
@@ -183,6 +172,7 @@ public void DuplicatePluginNameOnDeploy()
public void GetGetAssemblies()
{
#region Assemble
+
ServiceLocator.Init();
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
@"..\..\..\TestPlugin");
@@ -192,29 +182,30 @@ public void GetGetAssemblies()
// Get plugin config
var defaultPluginConfig = config.GetPluginsConfig("default");
var debugConfig = config.GetPluginsConfig("debug");
- #endregion
+
+ #endregion Assemble
#region Act
+
var defaultAssemblies = config.GetAssemblies(defaultPluginConfig[0]);
var debugAssemblies = config.GetAssemblies(debugConfig[0]);
- #endregion
+ #endregion Act
#region Assert
+
// The wildcard should return all 4 assemblies
- Assert.IsTrue(defaultAssemblies.Count>1, "The wildcard should return all assemblies");
+ Assert.IsTrue(defaultAssemblies.Count > 1, "The wildcard should return all assemblies");
// The specific assembly name should only return 1
Assert.AreEqual(1, debugAssemblies.Count, "The specific assembly name should only return 1");
- #endregion
-
+ #endregion Assert
}
[CrmPluginRegistrationAttribute("step", "step", "step", "step", IsolationModeEnum.Sandbox)]
[CrmPluginRegistrationAttribute("step", "step", "step", "step", IsolationModeEnum.Sandbox)]
public class TestPluginWithDuplicateAttributes
{
-
}
}
-}
+}
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks.Tests/IntegrationTests.playlist b/spkl/SparkleXrm.Tasks.Tests/IntegrationTests.playlist
new file mode 100644
index 00000000..3d84c54c
--- /dev/null
+++ b/spkl/SparkleXrm.Tasks.Tests/IntegrationTests.playlist
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj
index 8c125153..ded8896e 100644
--- a/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj
+++ b/spkl/SparkleXrm.Tasks.Tests/SparkleXrm.Tasks.Tests.csproj
@@ -44,60 +44,109 @@
Plugins.snk
-
- ..\packages\FakeItEasy.4.1.1\lib\net45\FakeItEasy.dll
+
+ ..\packages\FakeItEasy.5.5.0\lib\net45\FakeItEasy.dll
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Crm.Sdk.Proxy.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
+
+
+ ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll
False
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll
- ..\packages\Microsoft.CrmSdk.Deployment.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll
+ ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll
- ..\packages\Microsoft.CrmSdk.Workflow.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll
+ ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll
-
- ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.0.7\lib\net452\Microsoft.Xrm.Tooling.Connector.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Xrm.Tooling.Connector.dll
+
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
-
- ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
- True
+
+ ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll
+
+
+ ..\packages\System.Collections.Immutable.1.7.0\lib\netstandard2.0\System.Collections.Immutable.dll
+
+
+
-
- ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
+
+ ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll
+
+
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
+ True
+ True
+
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll
+ True
True
-
- ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll
+ True
True
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
+ True
+ True
+
+
@@ -113,6 +162,7 @@
+
diff --git a/spkl/SparkleXrm.Tasks.Tests/UnitTests.playlist b/spkl/SparkleXrm.Tasks.Tests/UnitTests.playlist
new file mode 100644
index 00000000..57135c72
--- /dev/null
+++ b/spkl/SparkleXrm.Tasks.Tests/UnitTests.playlist
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks.Tests/app.config b/spkl/SparkleXrm.Tasks.Tests/app.config
index 5719926d..e3c44456 100644
--- a/spkl/SparkleXrm.Tasks.Tests/app.config
+++ b/spkl/SparkleXrm.Tasks.Tests/app.config
@@ -21,7 +21,7 @@
-
+
@@ -63,6 +63,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spkl/SparkleXrm.Tasks.Tests/packages.config b/spkl/SparkleXrm.Tasks.Tests/packages.config
index d28400f7..d4327beb 100644
--- a/spkl/SparkleXrm.Tasks.Tests/packages.config
+++ b/spkl/SparkleXrm.Tasks.Tests/packages.config
@@ -1,12 +1,23 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs b/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs
index 20331219..67f1e750 100644
--- a/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs
+++ b/spkl/SparkleXrm.Tasks/Config/ConfigFile.cs
@@ -15,6 +15,7 @@ public class ConfigFile
public List plugins;
public List earlyboundtypes;
public List solutions;
+
[JsonIgnore]
public string filePath;
@@ -25,11 +26,12 @@ public virtual void Save()
{
File.Copy(file, file + DateTime.Now.ToString("yyyyMMddHHmmss") + ".bak");
}
- File.WriteAllText(file, Newtonsoft.Json.JsonConvert.SerializeObject(this,Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
+ File.WriteAllText(file, Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
}));
}
+
public virtual SolutionPackageConfig[] GetSolutionConfig(string profile)
{
if (solutions == null)
@@ -51,8 +53,8 @@ public virtual SolutionPackageConfig[] GetSolutionConfig(string profile)
}
return config;
-
}
+
public virtual EarlyBoundTypeConfig[] GetEarlyBoundConfig(string profile)
{
if (earlyboundtypes == null)
@@ -63,7 +65,7 @@ public virtual EarlyBoundTypeConfig[] GetEarlyBoundConfig(string profile)
generateOptionsetEnums = true,
generateStateEnums = true
} };
-
+
EarlyBoundTypeConfig[] config = null;
if (profile == "default")
{
@@ -99,14 +101,14 @@ public virtual WebresourceDeployConfig[] GetWebresourceConfig(string profile)
else
{
// Default profile or empty
- config = webresources.Where(c => c.profile==null || c.profile.Replace(" ", "").Split(',').Contains("default") || String.IsNullOrWhiteSpace(c.profile)).ToArray();
+ config = webresources.Where(c => c.profile == null || c.profile.Replace(" ", "").Split(',').Contains("default") || String.IsNullOrWhiteSpace(c.profile)).ToArray();
}
return config;
}
public virtual PluginDeployConfig[] GetPluginsConfig(string profile)
- {
+ {
PluginDeployConfig[] config = null;
if (plugins == null)
return new PluginDeployConfig[0];
@@ -118,12 +120,12 @@ public virtual PluginDeployConfig[] GetPluginsConfig(string profile)
if (profile != null)
{
- config = plugins.Where(c => c.profile!=null && c.profile.Replace(" ", "").Split(',').Contains(profile)).ToArray();
+ config = plugins.Where(c => c.profile != null && c.profile.Replace(" ", "").Split(',').Contains(profile)).ToArray();
}
else
{
// Default profile or empty
- config = plugins.Where(c => c.profile==null || c.profile.Replace(" ", "").Split(',').Contains("default") || String.IsNullOrWhiteSpace(c.profile)).ToArray();
+ config = plugins.Where(c => c.profile == null || c.profile.Replace(" ", "").Split(',').Contains("default") || String.IsNullOrWhiteSpace(c.profile)).ToArray();
}
return config;
@@ -135,15 +137,14 @@ public virtual List GetAssemblies(PluginDeployConfig plugin)
List assemblies;
var extension = Path.GetExtension(file);
-
+
if (extension == "") file = Path.Combine(file, "*.dll");
-
assemblies = ServiceLocator.DirectoryService.Search(this.filePath, file);
return assemblies;
}
-
}
+
public class ConfigFileService : IConfigFileService
{
public List FindConfig(string folder, bool raiseErrorIfNotFound = true)
@@ -169,7 +170,7 @@ public List FindConfig(string folder, bool raiseErrorIfNotFound = tr
foreach (var configPath in configfilePath)
{
// Check valid path and this is not the nuget package folder
- if (configPath != null && !Regex.IsMatch(configPath, @"packages\\spkl[0-9|.]*\\tools"))
+ if (configPath != null && !Regex.IsMatch(configPath, @"packages\\spkl"))
{
var config = Newtonsoft.Json.JsonConvert.DeserializeObject(File.ReadAllText(configPath));
config.filePath = Path.GetDirectoryName(configPath);
@@ -187,7 +188,5 @@ public List FindConfig(string folder, bool raiseErrorIfNotFound = tr
return results;
}
-
}
-
-}
+}
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs b/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs
index 2127652d..7e0d6f33 100644
--- a/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs
+++ b/spkl/SparkleXrm.Tasks/Config/EarlyBoundTypeConfig.cs
@@ -10,7 +10,9 @@ public class EarlyBoundTypeConfig
{
public string profile;
public string entities;
+ public string[] entityCollection;
public string actions;
+ public string[] actionCollection;
public bool generateOptionsetEnums;
public bool generateGlobalOptionsets;
public bool generateStateEnums;
diff --git a/spkl/SparkleXrm.Tasks/EntitiesTrim.cs b/spkl/SparkleXrm.Tasks/EntitiesTrim.cs
index e948cdd8..8fe675d3 100644
--- a/spkl/SparkleXrm.Tasks/EntitiesTrim.cs
+++ b/spkl/SparkleXrm.Tasks/EntitiesTrim.cs
@@ -791,6 +791,10 @@ public System.Nullable IsWorkflowActivity
{
return this.GetAttributeValue>("isworkflowactivity");
}
+ set
+ {
+ this.SetAttributeValue("isworkflowactivity", value);
+ }
}
///
diff --git a/spkl/SparkleXrm.Tasks/PluginRegistraton.cs b/spkl/SparkleXrm.Tasks/PluginRegistraton.cs
index 58b6a98b..8359c500 100644
--- a/spkl/SparkleXrm.Tasks/PluginRegistraton.cs
+++ b/spkl/SparkleXrm.Tasks/PluginRegistraton.cs
@@ -17,26 +17,14 @@ public class PluginRegistraton
private OrganizationServiceContext _ctx;
private IOrganizationService _service;
private ITrace _trace;
- private string[] _ignoredAssemblies = new string[] {
- "Microsoft.Crm.Sdk.Proxy.dll",
- "Microsoft.IdentityModel.dll",
- "Microsoft.Xrm.Sdk.dll",
- "Microsoft.Xrm.Sdk.Workflow.dll",
- "Microsoft.IdentityModel.Clients.ActiveDirectory.dll",
- "Microsoft.Extensions.FileSystemGlobbing.dll",
- "Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll",
- "Microsoft.Xrm.Sdk.Deployment.dll",
- "Microsoft.Xrm.Tooling.Connector.dll",
- "Newtonsoft.Json.dll",
- "SparkleXrm.Tasks.dll"
- };
+
public PluginRegistraton(IOrganizationService service, OrganizationServiceContext context, ITrace trace)
{
_ctx = context;
_service = service;
_trace = trace;
-
}
+
///
/// If not null, components are added to this solution
///
@@ -45,26 +33,27 @@ public PluginRegistraton(IOrganizationService service, OrganizationServiceContex
public void RegisterWorkflowActivities(string path)
{
var assemblyFilePath = new FileInfo(path);
- if (_ignoredAssemblies.Contains(assemblyFilePath.Name))
+ if (Reflection.IgnoredAssemblies.Contains(assemblyFilePath.Name))
return;
- // Load each assembly
- Assembly assembly = Reflection.ReflectionOnlyLoadAssembly(assemblyFilePath.FullName);
+ // Load each assembly
+ Assembly assembly = Reflection.LoadAssembly(assemblyFilePath.FullName);
if (assembly == null)
return;
- // Search for any types that interhit from IPlugin
+ AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, args) => Assembly.ReflectionOnlyLoad(args.Name);
+
+ // Search for any types that interhit from IPlugin
IEnumerable pluginTypes = Reflection.GetTypesInheritingFrom(assembly, typeof(System.Activities.CodeActivity));
if (pluginTypes.Count() > 0)
{
- var plugin = RegisterAssembly(assemblyFilePath, assembly, pluginTypes);
+ var plugin = RegisterAssembly(assemblyFilePath, assembly, pluginTypes, isWorkflowActivity: true);
if (plugin != null)
{
RegisterActivities(pluginTypes, plugin);
}
}
-
}
private void RegisterActivities(IEnumerable pluginTypes, PluginAssembly plugin)
@@ -73,17 +62,14 @@ private void RegisterActivities(IEnumerable pluginTypes, PluginAssembly pl
foreach (var pluginType in pluginTypes)
{
-
// Search for the CrmPluginStepAttribute
var pluginAttributes = pluginType.GetCustomAttributesData().Where(a => a.AttributeType.Name == typeof(CrmPluginRegistrationAttribute).Name);
PluginType sdkPluginType = null;
if (pluginAttributes.Count() > 0)
{
-
if (pluginAttributes.Count() > 1)
{
Debug.WriteLine("Workflow Activities can only have a single registration");
-
}
var workflowActivitiy = pluginAttributes.First().CreateFromData();
@@ -117,16 +103,12 @@ private void RegisterActivities(IEnumerable pluginTypes, PluginAssembly pl
// Update
_service.Update(sdkPluginType);
}
-
-
-
}
}
}
private void AddAssemblyToSolution(string solutionName, PluginAssembly assembly)
{
-
// Find solution
AddSolutionComponentRequest addToSolution = new AddSolutionComponentRequest()
{
@@ -137,7 +119,6 @@ private void AddAssemblyToSolution(string solutionName, PluginAssembly assembly)
};
_trace.WriteLine("Adding to solution '{0}'", solutionName);
_service.Execute(addToSolution);
-
}
private void AddTypeToSolution(string solutionName, PluginType sdkPluginType)
@@ -152,6 +133,7 @@ private void AddTypeToSolution(string solutionName, PluginType sdkPluginType)
_trace.WriteLine("Adding to solution '{0}'", solutionName);
_service.Execute(addToSolution);
}
+
private void AddStepToSolution(string solutionName, SdkMessageProcessingStep sdkPluginType)
{
// Find solution
@@ -164,25 +146,24 @@ private void AddStepToSolution(string solutionName, SdkMessageProcessingStep sdk
};
_trace.WriteLine("Adding to solution '{0}'", solutionName);
_service.Execute(addToSolution);
-
}
-
public void RegisterPlugin(string file, bool excludePluginSteps = false)
{
var assemblyFilePath = new FileInfo(file);
- if (_ignoredAssemblies.Contains(assemblyFilePath.Name))
+ if (assemblyFilePath.Name.StartsWith("System.") || Reflection.IgnoredAssemblies.Contains(assemblyFilePath.Name))
return;
- // Load each assembly
- Assembly peekAssembly = Reflection.ReflectionOnlyLoadAssembly(assemblyFilePath.FullName);
+ // Load each assembly
+ Assembly peekAssembly = Reflection.LoadAssembly(assemblyFilePath.FullName);
if (peekAssembly == null)
return;
+
_trace.WriteLine("Checking assembly '{0}' for plugins", assemblyFilePath.Name);
- // Search for any types that interhit from IPlugin
+ // Search for any types that interhit from IPlugin
IEnumerable pluginTypes = Reflection.GetTypesImplementingInterface(peekAssembly, typeof(Microsoft.Xrm.Sdk.IPlugin));
if (pluginTypes.Count() > 0)
@@ -192,17 +173,15 @@ public void RegisterPlugin(string file, bool excludePluginSteps = false)
var plugin = RegisterAssembly(assemblyFilePath, peekAssembly, pluginTypes);
if (plugin != null)
- if (plugin != null && !excludePluginSteps)
- {
- RegisterPluginSteps(pluginTypes, plugin);
- }
+ if (plugin != null && !excludePluginSteps)
+ {
+ RegisterPluginSteps(pluginTypes, plugin);
+ }
}
-
}
- private PluginAssembly RegisterAssembly(FileInfo assemblyFilePath, Assembly assembly, IEnumerable pluginTypes)
+ private PluginAssembly RegisterAssembly(FileInfo assemblyFilePath, Assembly assembly, IEnumerable pluginTypes, bool isWorkflowActivity = false)
{
-
// Get the isolation mode of the first attribute
var firstType = Reflection.GetAttributes(pluginTypes, typeof(CrmPluginRegistrationAttribute).Name).FirstOrDefault();
if (firstType == null)
@@ -246,7 +225,7 @@ private PluginAssembly RegisterAssembly(FileInfo assemblyFilePath, Assembly asse
}
else
{
- UnregisterRemovedPluginTypes(pluginTypes, plugin);
+ UnregisterRemovedPluginTypes(pluginTypes, plugin, isWorkflowActivity);
_trace.WriteLine("Updating Plugin '{0}' from '{1}'", plugin.Name, assemblyFilePath.FullName);
// Update
@@ -262,11 +241,11 @@ private PluginAssembly RegisterAssembly(FileInfo assemblyFilePath, Assembly asse
return plugin;
}
- private void UnregisterRemovedPluginTypes(IEnumerable pluginTypes, PluginAssembly plugin)
+ private void UnregisterRemovedPluginTypes(IEnumerable pluginTypes, PluginAssembly plugin, bool isWorkflowActivity = false)
{
_trace.WriteLine("Checking for orphaned PluginTypes: '{0}' ", plugin.Name);
- var sdkPluginTypes = ServiceLocator.Queries.GetPluginTypes(_ctx, plugin);
+ var sdkPluginTypes = ServiceLocator.Queries.GetPluginTypes(_ctx, plugin).Where(t => (t.IsWorkflowActivity ?? false) == isWorkflowActivity);
foreach (var sdkPluginType in sdkPluginTypes)
{
@@ -294,7 +273,6 @@ private void RegisterPluginSteps(IEnumerable pluginTypes, PluginAssembly p
foreach (var pluginType in pluginTypes)
{
-
// Search for the CrmPluginStepAttribute
var pluginAttributes = pluginType.GetCustomAttributesData().Where(a => a.AttributeType.Name == typeof(CrmPluginRegistrationAttribute).Name);
PluginType sdkPluginType = null;
@@ -367,14 +345,11 @@ private List GetExistingSteps(PluginType sdkPluginType
AsyncAutoDelete = s.AsyncAutoDelete,
Attributes = s.Attributes,
SdkMessageFilterId = s.SdkMessageFilterId
-
}).ToList();
return steps;
-
}
-
private void RegisterStep(PluginType sdkPluginType, List existingSteps, CustomAttributeData pluginAttribute)
{
var pluginStep = (CrmPluginRegistrationAttribute)pluginAttribute.CreateFromData();
@@ -433,9 +408,11 @@ private void RegisterStep(PluginType sdkPluginType, List existingImages, string imageName, ImageTypeEnum imagetype, string attributes)
{
if (String.IsNullOrWhiteSpace(imageName))
@@ -525,15 +498,18 @@ private SdkMessageProcessingStepImage RegisterImage(CrmPluginRegistrationAttribu
case "Create":
image.MessagePropertyName = "Id";
break;
+
case "SetState":
case "SetStateDynamicEntity":
image.MessagePropertyName = "EntityMoniker";
break;
+
case "Send":
case "DeliverIncoming":
case "DeliverPromote":
image.MessagePropertyName = "EmailId";
break;
+
default:
image.MessagePropertyName = "Target";
break;
@@ -553,4 +529,4 @@ private SdkMessageProcessingStepImage RegisterImage(CrmPluginRegistrationAttribu
return image;
}
}
-}
+}
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks/Reflection.cs b/spkl/SparkleXrm.Tasks/Reflection.cs
index 817e6f4d..c2d25204 100644
--- a/spkl/SparkleXrm.Tasks/Reflection.cs
+++ b/spkl/SparkleXrm.Tasks/Reflection.cs
@@ -10,9 +10,23 @@
namespace SparkleXrm.Tasks
{
- public class Reflection
+ public class Reflection
{
-
+ public static string[] IgnoredAssemblies = new string[] {
+ "Microsoft.Crm.Sdk.Proxy.dll",
+ "Microsoft.IdentityModel.dll",
+ "Microsoft.Xrm.Sdk.dll",
+ "Microsoft.Xrm.Sdk.Workflow.dll",
+ "Microsoft.IdentityModel.Clients.ActiveDirectory.dll",
+ "Microsoft.Extensions.FileSystemGlobbing.dll",
+ "Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll",
+ "Microsoft.Xrm.Sdk.Deployment.dll",
+ "Microsoft.Xrm.Tooling.Connector.dll",
+ "Newtonsoft.Json.dll",
+ "SparkleXrm.Tasks.dll",
+ "System.Net.Http.dll",
+ "Microsoft.Rest.ClientRuntime.dll"
+ };
public static Assembly LoadAssembly(string path)
{
@@ -25,75 +39,31 @@ public static Assembly LoadAssembly(string path)
{
// Assembly already loaded so skip
Debug.WriteLine("Assembly load error:" + ex.Message);
-
}
return assembly;
}
- public static Assembly ReflectionOnlyLoadAssembly(string path)
- {
- string[] ignore = new string[] { "Microsoft.Crm.Sdk.Proxy.dll", "Microsoft.IdentityModel.dll", "Microsoft.Xrm.Sdk.dll","Microsoft.Xrm.Sdk.Workflow.dll" };
- if (ignore.Where(a => path.Contains(a)).FirstOrDefault() != null)
- return null;
-
- Assembly assembly = null;
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
- try
- {
- assembly = Assembly.ReflectionOnlyLoadFrom(path);
- }
- catch (FileLoadException ex)
- {
- // Assembly already loaded so skip
- Debug.WriteLine("Assembly load error:" + ex.Message);
-
- }
- finally
- {
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve;
- }
- return assembly;
- }
-
- private static Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
- {
- Assembly assembly;
- string[] parts = args.Name.Split(',');
- switch (parts[0])
- {
- case "Microsoft.Xrm.Sdk":
- assembly = System.Reflection.Assembly.ReflectionOnlyLoad(parts[0].Trim());
- break;
- case "Microsoft.Crm.Sdk.Proxy":
- assembly = System.Reflection.Assembly.ReflectionOnlyLoad(parts[0].Trim());
- break;
- default:
- assembly = System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
- break;
- }
-
- return assembly;
- }
-
public static IEnumerable GetTypesImplementingInterface(Assembly assembly, Type interfaceName)
{
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
- var types = assembly.DefinedTypes.Where(p => p.GetInterfaces().FirstOrDefault(a => a.Name == interfaceName.Name) != null);
+ var types = assembly.ExportedTypes.Where(p => p.GetInterfaces().FirstOrDefault(a => a.Name == interfaceName.Name) != null);
Trace.WriteLine(types.FirstOrDefault()?.CustomAttributes.Count());
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve;
return types;
}
public static IEnumerable GetTypesInheritingFrom(Assembly assembly, Type type)
{
- // Load the containing assembly into the reflection context so that we can find all types deriving from System.Activities.CodeActivity
- System.Reflection.Assembly.ReflectionOnlyLoad(type.Assembly.FullName);
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += CurrentDomain_ReflectionOnlyAssemblyResolve;
- var containingAssembly = AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies().Where(ab => ab.GetType(type.FullName) != null).First();
- var types = assembly.DefinedTypes.Where(p => containingAssembly.GetType(type.FullName).IsAssignableFrom(p));
- AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve -= CurrentDomain_ReflectionOnlyAssemblyResolve;
- return types;
+ var definedTypes = assembly.DefinedTypes.Where(p => p.BaseType != null && p.BaseType.Name == type.Name).ToList();
+
+ var allTypes = new List(definedTypes);
+ foreach (var abstractType in definedTypes.Where(t => t.IsAbstract))
+ {
+ var inheritingTypes = assembly.DefinedTypes.Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(abstractType.UnderlyingSystemType)).ToList();
+ allTypes.AddRange(inheritingTypes);
+ }
+
+ return allTypes;
}
+
public static IEnumerable GetAttributes(IEnumerable types, string attributeName)
{
List attributes = new List();
@@ -109,12 +79,8 @@ public static IEnumerable GetAttributes(IEnumerable t
}
attributes.AddRange(data);
}
-
+
return attributes;
}
-
-
-
}
-
-}
+}
\ No newline at end of file
diff --git a/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj b/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj
index 281cdc60..79bcf8a7 100644
--- a/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj
+++ b/spkl/SparkleXrm.Tasks/SparkleXrm.Tasks.csproj
@@ -38,41 +38,40 @@
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.5\lib\net452\Microsoft.Crm.Sdk.Proxy.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll
True
-
- ..\packages\Microsoft.Extensions.FileSystemGlobbing.2.0.0\lib\netstandard2.0\Microsoft.Extensions.FileSystemGlobbing.dll
+
+ ..\packages\Microsoft.Extensions.FileSystemGlobbing.3.1.0\lib\netstandard2.0\Microsoft.Extensions.FileSystemGlobbing.dll
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
- True
-
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
- True
+
+ ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
False
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll
+ True
+
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.5\lib\net452\Microsoft.Xrm.Sdk.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll
True
- ..\packages\Microsoft.CrmSdk.Deployment.9.0.0.5\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll
+ ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll
True
- ..\packages\Microsoft.CrmSdk.Workflow.9.0.0.5\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll
+ ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll
-
- ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.0.7\lib\net452\Microsoft.Xrm.Tooling.Connector.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Xrm.Tooling.Connector.dll
True
-
- ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
@@ -81,13 +80,43 @@
+
+
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
+ True
+ True
+
+
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
+ True
+ True
+
+
@@ -144,6 +173,7 @@
+
@@ -158,16 +188,25 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/TestPluginWorkflowCombined/WorkFlowActivityBase.cs b/spkl/TestPluginWorkflowCombined/WorkFlowActivityBase.cs
new file mode 100644
index 00000000..39124684
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/WorkFlowActivityBase.cs
@@ -0,0 +1,321 @@
+//
+// Copyright (c) 2017 All Rights Reserved
+//
+//
+// 4/17/2017 12:29:58 PM
+// Implements the WorkFlowActivityBase Workflow Activity.
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.1
+//
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.ServiceModel;
+using System.Threading.Tasks;
+using System.Activities;
+using Microsoft.Xrm.Sdk;
+using Microsoft.Xrm.Sdk.Workflow;
+using System.Runtime.Serialization;
+
+namespace CrmVSSolution4.WorkflowActivityLibrary1
+{
+ public abstract class WorkFlowActivityBase : CodeActivity
+ {
+
+ public sealed class LocalWorkflowContext
+ {
+ internal IServiceProvider ServiceProvider
+ {
+ get;
+
+ private set;
+ }
+
+ internal IOrganizationService OrganizationService
+ {
+ get;
+
+ private set;
+ }
+
+ internal IWorkflowContext WorkflowExecutionContext
+ {
+ get;
+
+ private set;
+ }
+
+ internal ITracingService TracingService
+ {
+ get;
+
+ private set;
+ }
+
+ private LocalWorkflowContext()
+ {
+ }
+
+ internal LocalWorkflowContext(CodeActivityContext executionContext)
+ {
+ if (executionContext == null)
+ {
+ throw new ArgumentNullException("serviceProvider");
+ }
+
+ // Obtain the execution context service from the service provider.
+ this.WorkflowExecutionContext = (IWorkflowContext)executionContext.GetExtension();
+
+ // Obtain the tracing service from the service provider.
+ this.TracingService = (ITracingService)executionContext.GetExtension();
+
+ // Obtain the Organization Service factory service from the service provider
+ IOrganizationServiceFactory factory = (IOrganizationServiceFactory)executionContext.GetExtension();
+
+ // Use the factory to generate the Organization Service.
+ this.OrganizationService = factory.CreateOrganizationService(this.WorkflowExecutionContext.UserId);
+ }
+
+ internal void Trace(string message)
+ {
+ if (string.IsNullOrWhiteSpace(message) || this.TracingService == null)
+ {
+ return;
+ }
+
+ if (this.WorkflowExecutionContext == null)
+ {
+ this.TracingService.Trace(message);
+ }
+ else
+ {
+ this.TracingService.Trace(
+ "{0}, Correlation Id: {1}, Initiating User: {2}",
+ message,
+ this.WorkflowExecutionContext.CorrelationId,
+ this.WorkflowExecutionContext.InitiatingUserId);
+ }
+ }
+ }
+
+ protected override void Execute(CodeActivityContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException("serviceProvider");
+ }
+
+ // Construct the Local plug-in context.
+ LocalWorkflowContext localcontext = new LocalWorkflowContext(context);
+
+ //localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Entered {0}.Execute()", this.ChildClassName));
+
+ try
+ {
+ //// Iterate over all of the expected registered events to ensure that the plugin
+ //// has been invoked by an expected event
+ //// For any given plug-in event at an instance in time, we would expect at most 1 result to match.
+ //Action entityAction =
+ // (from a in this.RegisteredEvents
+ // where (
+ // a.Item1 == localcontext.PluginExecutionContext.Stage &&
+ // a.Item2 == localcontext.PluginExecutionContext.MessageName &&
+ // (string.IsNullOrWhiteSpace(a.Item3) ? true : a.Item3 == localcontext.PluginExecutionContext.PrimaryEntityName)
+ // )
+ // select a.Item4).FirstOrDefault();
+
+ //if (entityAction != null)
+ //{
+ // localcontext.Trace(string.Format(
+ // CultureInfo.InvariantCulture,
+ // "{0} is firing for Entity: {1}, Message: {2}",
+ // this.ChildClassName,
+ // localcontext.PluginExecutionContext.PrimaryEntityName,
+ // localcontext.PluginExecutionContext.MessageName));
+
+ // entityAction.Invoke(localcontext);
+
+ // // now exit - if the derived plug-in has incorrectly registered overlapping event registrations,
+ // // guard against multiple executions.
+ // return;
+ //}
+ ExecuteCRMWorkFlowActivity(context, localcontext);
+
+ }
+ catch (FaultException e)
+ {
+ localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Exception: {0}", e.ToString()));
+
+ // Handle the exception.
+ throw;
+ }
+ finally
+ {
+ //localcontext.Trace(string.Format(CultureInfo.InvariantCulture, "Exiting {0}.Execute()", this.ChildClassName));
+ }
+ }
+
+ public virtual void ExecuteCRMWorkFlowActivity(CodeActivityContext context, LocalWorkflowContext crmWorkflowContext)
+ {
+ // Do nothing.
+ }
+
+
+
+
+
+ //public IWorkflowContext ParentContext
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public string StageName
+ //{
+ // get { throw new NotImplementedException(); }
+ // }
+
+ //public int WorkflowCategory
+ //{
+ // get { throw new NotImplementedException(); }
+ // }
+
+ //public int WorkflowMode
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid BusinessUnitId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid CorrelationId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public int Depth
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid InitiatingUserId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public ParameterCollection InputParameters
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public bool IsExecutingOffline
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public bool IsInTransaction
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public bool IsOfflinePlayback
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public int IsolationMode
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public string MessageName
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public int Mode
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public DateTime OperationCreatedOn
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid OperationId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid OrganizationId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public string OrganizationName
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public ParameterCollection OutputParameters
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public EntityReference OwningExtension
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public EntityImageCollection PostEntityImages
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public EntityImageCollection PreEntityImages
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid PrimaryEntityId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public string PrimaryEntityName
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid? RequestId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public string SecondaryEntityName
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public ParameterCollection SharedVariables
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+
+ //public Guid UserId
+ //{
+ // get { throw new NotImplementedException(); }
+ //}
+ //protected override void Execute(CodeActivityContext context)
+ //{
+ // throw new NotImplementedException();
+ //}
+ }
+}
diff --git a/spkl/TestPluginWorkflowCombined/WorkflowActivity.cs b/spkl/TestPluginWorkflowCombined/WorkflowActivity.cs
new file mode 100644
index 00000000..ef3f4baa
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/WorkflowActivity.cs
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2017 All Rights Reserved
+//
+//
+// 4/17/2017 12:30:49 PM
+// Implements the WorkflowActivity Workflow Activity.
+namespace TestWFSolution.WorkflowActivityLibrary1
+{
+ using System;
+ using System.Activities;
+ using System.ServiceModel;
+ using Microsoft.Xrm.Sdk;
+ using Microsoft.Xrm.Sdk.Workflow;
+
+ [CrmPluginRegistration(
+ "WorkflowActivity", "f584fb06-dc73-4cd8-b234-626cb5962293","Description","Group Name",IsolationModeEnum.Sandbox
+ )]
+ public sealed class WorkflowActivity : CodeActivity
+ {
+ ///
+ /// Executes the workflow activity.
+ ///
+ /// The execution context.
+ protected override void Execute(CodeActivityContext executionContext)
+ {
+ // Create the tracing service
+ ITracingService tracingService = executionContext.GetExtension();
+
+ if (tracingService == null)
+ {
+ throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
+ }
+
+ tracingService.Trace("Entered WorkflowActivity.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}",
+ executionContext.ActivityInstanceId,
+ executionContext.WorkflowInstanceId);
+
+ // Create the context
+ IWorkflowContext context = executionContext.GetExtension();
+
+ if (context == null)
+ {
+ throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
+ }
+
+ tracingService.Trace("WorkflowActivity.Execute(), Correlation Id: {0}, Initiating User: {1}",
+ context.CorrelationId,
+ context.InitiatingUserId);
+
+ IOrganizationServiceFactory serviceFactory = executionContext.GetExtension();
+ IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
+
+ try
+ {
+ // TODO: Implement your custom Workflow business logic.
+ }
+ catch (FaultException e)
+ {
+ tracingService.Trace("Exception: {0}", e.ToString());
+
+ // Handle the exception.
+ throw;
+ }
+
+ tracingService.Trace("Exiting WorkflowActivity.Execute(), Correlation Id: {0}", context.CorrelationId);
+ }
+ }
+}
\ No newline at end of file
diff --git a/spkl/TestPluginWorkflowCombined/WorkflowActivityInheritingFromWorkflowActivityBase.cs b/spkl/TestPluginWorkflowCombined/WorkflowActivityInheritingFromWorkflowActivityBase.cs
new file mode 100644
index 00000000..f18299fc
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/WorkflowActivityInheritingFromWorkflowActivityBase.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Activities;
+using Microsoft.Xrm.Sdk;
+using System.ServiceModel;
+using Microsoft.Xrm.Sdk.Workflow;
+using CrmVSSolution4.WorkflowActivityLibrary1;
+
+namespace TestWFSolution.WorkflowActivityLibrary1
+{
+ [CrmPluginRegistration(
+ "WorkflowActivityInheritingFromWorkflowActivityBase", "93AB069C-188B-4929-BF1E-9622DEDD5209", "Description", "Group Name", IsolationModeEnum.Sandbox
+ )]
+ public class WorkflowActivityInheritingFromWorkflowActivityBase : WorkFlowActivityBase
+ {
+
+ ///
+ /// Executes the WorkFlow.
+ ///
+ /// The which contains the
+ ///
+ ///
+ ///
+ /// For improved performance, Microsoft Dynamics 365 caches WorkFlow instances.
+ /// The WorkFlow's Execute method should be written to be stateless as the constructor
+ /// is not called for every invocation of the WorkFlow. Also, multiple system threads
+ /// could execute the WorkFlow at the same time. All per invocation state information
+ /// is stored in the context. This means that you should not use global variables in WorkFlows.
+ ///
+ public override void ExecuteCRMWorkFlowActivity(CodeActivityContext executionContext, LocalWorkflowContext crmWorkflowContext)
+ {
+
+ if (crmWorkflowContext == null)
+ {
+ throw new ArgumentNullException("crmWorkflowContext");
+ }
+
+ try
+ {
+ // TODO: Implement your custom activity handling.
+ }
+ catch (FaultException e)
+ {
+ // Handle the exception.
+ throw e;
+ }
+ }
+ }
+}
diff --git a/spkl/TestPluginWorkflowCombined/app.config b/spkl/TestPluginWorkflowCombined/app.config
new file mode 100644
index 00000000..50f6b166
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/app.config
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/TestPluginWorkflowCombined/deploy-plugins.bat b/spkl/TestPluginWorkflowCombined/deploy-plugins.bat
new file mode 100644
index 00000000..9bd05314
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/deploy-plugins.bat
@@ -0,0 +1,14 @@
+@echo off
+set package_root=..\
+REM Find the spkl in the package folder (irrespective of version)
+For /R %package_root% %%G IN (spkl.exe) do (
+ IF EXIST "%%G" (set spkl_path=%%G
+ goto :continue)
+ )
+
+:continue
+@echo Using '%spkl_path%'
+REM spkl plugins [path] [connection-string] [/p:release]
+"%spkl_path%" plugins
+
+pause
\ No newline at end of file
diff --git a/spkl/TestPluginWorkflowCombined/packages.config b/spkl/TestPluginWorkflowCombined/packages.config
new file mode 100644
index 00000000..7d9031ca
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/packages.config
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/TestPluginWorkflowCombined/spkl.json b/spkl/TestPluginWorkflowCombined/spkl.json
new file mode 100644
index 00000000..68b15cb8
--- /dev/null
+++ b/spkl/TestPluginWorkflowCombined/spkl.json
@@ -0,0 +1,21 @@
+{
+ "plugins": [
+ {
+ "assemblypath": "bin\\Debug\\TestPluginWFCombined.dll",
+ "classRegex": "((public( sealed)? class (?'class'[\\w]*)[\\W]*?)((?'plugin':[\\W]*?((IPlugin)|(PluginBase)|(Plugin)))|(?'wf':[\\W]*?CodeActivity)))"
+ }
+ ],
+ "earlyboundtypes": [
+ {
+ "profile": "default",
+ "entities": "account,contact,quote,goal",
+ "actions": "dev1_simpleaction",
+ "generateOptionsetEnums": true,
+ "generateGlobalOptionsets": false,
+ "generateStateEnums": true,
+ "filename": "EarlyBoundTypes.cs",
+ "classNamespace": "TestPlugin",
+ "serviceContextName": "XrmSvc"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/spkl/TestWorkflowActivity/TestWorkflowActivity.csproj b/spkl/TestWorkflowActivity/TestWorkflowActivity.csproj
index 8b2f33de..5d436913 100644
--- a/spkl/TestWorkflowActivity/TestWorkflowActivity.csproj
+++ b/spkl/TestWorkflowActivity/TestWorkflowActivity.csproj
@@ -38,25 +38,28 @@
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Crm.Sdk.Proxy.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
+
+ ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
-
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll
- ..\packages\Microsoft.CrmSdk.Deployment.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll
+ ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll
- ..\packages\Microsoft.CrmSdk.Workflow.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll
+ ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll
-
- ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.0.7\lib\net452\Microsoft.Xrm.Tooling.Connector.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Xrm.Tooling.Connector.dll
+
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
@@ -65,13 +68,33 @@
+
+
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
+
+
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
+
+
@@ -80,7 +103,6 @@
-
diff --git a/spkl/TestWorkflowActivity/app.config b/spkl/TestWorkflowActivity/app.config
index a01b86a1..cf1c053c 100644
--- a/spkl/TestWorkflowActivity/app.config
+++ b/spkl/TestWorkflowActivity/app.config
@@ -2,5 +2,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/TestWorkflowActivity/packages.config b/spkl/TestWorkflowActivity/packages.config
index febd59d4..7d9031ca 100644
--- a/spkl/TestWorkflowActivity/packages.config
+++ b/spkl/TestWorkflowActivity/packages.config
@@ -1,8 +1,15 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/spkl.sln b/spkl/spkl.sln
index 0ee38620..a769b361 100644
--- a/spkl/spkl.sln
+++ b/spkl/spkl.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26730.12
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleXrm.Tasks", "SparkleXrm.Tasks\SparkleXrm.Tasks.csproj", "{439FFD12-81E6-41DD-8AED-35A526051D45}"
EndProject
@@ -41,6 +41,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrmSvcUtil.FilteringService
EndProject
Project("{F5034706-568F-408A-B7B3-4D38C6DB8A32}") = "BuildTasks", "BuildTasks\BuildTasks.pssproj", "{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestPluginWorkflowCombined", "TestPluginWorkflowCombined\TestPluginWorkflowCombined.csproj", "{147A132A-D2FF-46FA-8EBA-132BBB3DA405}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -113,6 +115,14 @@ Global
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|Any CPU.Build.0 = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x86.ActiveCfg = Release|Any CPU
{6CAFC0C6-A428-4D30-A9F9-700E829FEA51}.Release|x86.Build.0 = Release|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Debug|x86.Build.0 = Debug|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Release|Any CPU.Build.0 = Release|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Release|x86.ActiveCfg = Release|Any CPU
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -122,6 +132,7 @@ Global
{57E6527B-0860-4208-986B-776C9B159A41} = {A40D37EB-2570-43F8-B852-82C91A5A101D}
{E1D15DFB-F2BA-40F5-8C1C-34482C1D74B6} = {A40D37EB-2570-43F8-B852-82C91A5A101D}
{A9FDFE00-5D28-47C6-863D-41C463D6FC5E} = {A40D37EB-2570-43F8-B852-82C91A5A101D}
+ {147A132A-D2FF-46FA-8EBA-132BBB3DA405} = {A40D37EB-2570-43F8-B852-82C91A5A101D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F41929D6-0D4E-46F0-8FEC-EFDADE19CC3D}
diff --git a/spkl/spkl/App.config b/spkl/spkl/App.config
index 83ef53d4..13ee2802 100644
--- a/spkl/spkl/App.config
+++ b/spkl/spkl/App.config
@@ -23,11 +23,11 @@
-
+
-
+
@@ -70,6 +70,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spkl/spkl/CommandLineArgs.cs b/spkl/spkl/CommandLineArgs.cs
index aa699848..1b857c49 100644
--- a/spkl/spkl/CommandLineArgs.cs
+++ b/spkl/spkl/CommandLineArgs.cs
@@ -7,7 +7,7 @@
namespace SparkleXrmTask
{
- [CommandLineArguments(Program = "spkl", Title = "SpakleXrm Deployment Tasks", Description = "Let SparkleXrm do the work for you!")]
+ [CommandLineArguments(Program = "spkl", Title = "SparkleXrm Deployment Tasks", Description = "Let SparkleXrm do the work for you!")]
public class CommandLineArgs
{
[CommandLineParameter(Command = "?", Default = false, Description = "Show Help", Name = "Help", IsHelp = true)]
@@ -26,7 +26,6 @@ public class CommandLineArgs
pack = Packs an unpacked solution into a new Solution Zip - grabbing the latest assemblies and webresources from their mapped locations
import = Packs a solution as per the 'pack' task, and then imports into Dynamics 365
")]
-
public string Task { get; set; }
[CommandLineParameter(Name = "Overwrite", Command = "o", Required = false, Description = "Optional overwrite webresource files when downloading webresources")]
@@ -41,7 +40,7 @@ public class CommandLineArgs
[CommandLineParameter(Name = "profile", Command = "p", ParameterIndex = 4, Required = false, Description = "Optional profile name. If ommitted, default will be used")]
public string Profile { get; set; }
- [CommandLineParameter(Name = "solution prefix", Command= "s", Required = false, Description = "Optional Prefix to filter webresources when downloading the config.")]
+ [CommandLineParameter(Name = "solution prefix", Command = "s", Required = false, Description = "Optional Prefix to filter webresources when downloading the config.")]
public string Prefix { get; set; }
[CommandLineParameter(Name = "Wait for keypress", Command = "w", Required = false, Description = "Optional wait for a key press at the end of task run")]
@@ -52,5 +51,8 @@ public class CommandLineArgs
[CommandLineParameter(Name = "Exclude Plugin Steps", Command = "e", Required = false, Description = "Exclude plugin steps when deploying plugins")]
public bool ExcludePluginSteps { get; set; }
+
+ [CommandLineParameter(Name = "Legacy Login Mode", Command = "l", Required = false, Description = "Use the legacy command line login mode")]
+ public bool LegacyLogin { get; set; }
}
-}
+}
\ No newline at end of file
diff --git a/spkl/spkl/Package/spkl.nuspec b/spkl/spkl/Package/spkl.nuspec
index 982fa28c..501e8f1a 100644
--- a/spkl/spkl/Package/spkl.nuspec
+++ b/spkl/spkl/Package/spkl.nuspec
@@ -1,53 +1,53 @@
-
- spkl
- 1.0.0$suffix$
- spkl - Dynamics 365 deployment task runner
- Scott Durow
- https://github.com/scottdurow/SparkleXrm/blob/master/MIT-License.txt
- https://github.com/scottdurow/SparkleXrm/wiki/spkl
- https://raw.githubusercontent.com/scottdurow/SparkleXrm/master/NuGet/SparkleXRM.png
- true
- Simple and Lightweight deployment task runner for Dynamics 365
- $releasenotes$
- en-GB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ spkl
+ 1.0.0$suffix$
+ spkl - Dynamics 365 deployment task runner
+ Scott Durow
+ https://github.com/scottdurow/SparkleXrm/blob/master/MIT-License.txt
+ https://github.com/scottdurow/SparkleXrm/wiki/spkl
+ https://raw.githubusercontent.com/scottdurow/SparkleXrm/master/NuGet/SparkleXRM.png
+ true
+ Simple and Lightweight deployment task runner for Dynamics 365
+ $releasenotes$
+ en-GB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spkl/spkl/Program.cs b/spkl/spkl/Program.cs
index 9e8bec37..f314b441 100644
--- a/spkl/spkl/Program.cs
+++ b/spkl/spkl/Program.cs
@@ -1,11 +1,11 @@
-
-using CmdLine;
+using CmdLine;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Sdk.Samples;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Tooling.Connector;
using SparkleXrm.Tasks;
+using SparkleXrmTask.XrmToolingCmdLine;
using System;
using System.Collections.Generic;
using System.IO;
@@ -18,20 +18,28 @@
namespace SparkleXrmTask
{
- class Program
- {
- static void Main(string[] args)
+ internal class Program
+ {
+ private static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.DarkYellow;
+ Console.WriteLine(@"
+ __ .__
+ ____________ | | _| |
+ / ___/\____ \| |/ / |
+ \___ \ | |_> > <| |__
+/____ >| __/|__|_ \____/
+ \/ |__| \/ ");
+
Console.WriteLine("spkl Task Runner v" + Assembly.GetEntryAssembly().GetName().Version + "\tTasks v" + Assembly.GetAssembly(typeof(SparkleXrm.Tasks.BaseTask)).GetName().Version);
-
+
Console.ForegroundColor = ConsoleColor.Gray;
bool error = false;
CommandLineArgs arguments = null;
try
{
arguments = CommandLine.Parse();
-
+
Run(arguments);
}
catch (CommandLineException exception)
@@ -87,12 +95,12 @@ static void Main(string[] args)
Console.WriteLine(ex.Message);
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.WriteLine(ex.StackTrace);
-
+
// Display the details of the inner exception.
if (ex.InnerException != null)
{
Console.WriteLine(ex.InnerException.Message);
-
+
FaultException fe = ex.InnerException
as FaultException;
if (fe != null)
@@ -121,7 +129,7 @@ static void Main(string[] args)
Environment.ExitCode = 1;
}
}
- if (arguments!=null && arguments.WaitForKey == true)
+ if (arguments != null && arguments.WaitForKey == true)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Press any key...");
@@ -142,18 +150,32 @@ private static void Run(CommandLineArgs arguments)
if (arguments.Connection == null)
{
- // No Connection is supplied to ask for connection on command line
- ServerConnection serverConnect = new ServerConnection();
- ServerConnection.Configuration config = serverConnect.GetServerConfiguration(arguments.IgnoreLocalPrincipal);
-
- arguments.Connection = BuildConnectionString(config);
+ if (arguments.LegacyLogin)
+ {
+ Console.ForegroundColor = ConsoleColor.Blue;
+ Console.Write("On-premises/Legacy Login");
+ Console.ForegroundColor = ConsoleColor.Gray;
+ // This login code will not work with the latest versions of CDS
+ // No Connection is supplied to ask for connection on command line
+ ServerConnection serverConnect = new ServerConnection();
+ ServerConnection.Configuration config = serverConnect.GetServerConfiguration(arguments.IgnoreLocalPrincipal);
+
+ arguments.Connection = BuildConnectionString(config);
- using (var serviceProxy = new OrganizationServiceProxy(config.OrganizationUri, config.HomeRealmUri, config.Credentials, config.DeviceCredentials))
+ using (var serviceProxy = new OrganizationServiceProxy(config.OrganizationUri, config.HomeRealmUri, config.Credentials, config.DeviceCredentials))
+ {
+ // This statement is required to enable early-bound type support.
+ serviceProxy.EnableProxyTypes();
+ serviceProxy.Timeout = new TimeSpan(1, 0, 0);
+ RunTask(arguments, serviceProxy, trace);
+ }
+ }
+ else
{
- // This statement is required to enable early-bound type support.
- serviceProxy.EnableProxyTypes();
- serviceProxy.Timeout = new TimeSpan(1, 0, 0);
- RunTask(arguments, serviceProxy, trace);
+ var toolingConnector = new XrmToolingConnection();
+ var client = toolingConnector.Connect();
+ arguments.Connection = toolingConnector.ConnectionString;
+ RunTask(arguments, client, trace);
}
}
else if (arguments.Connection == "")
@@ -173,15 +195,14 @@ private static void Run(CommandLineArgs arguments)
var password = ConsoleEx.ReadPassword('*');
arguments.Connection = arguments.Connection.Replace(passwordMatch.Value, "Password=" + password);
}
-
+ CrmServiceClient.MaxConnectionTimeout = new TimeSpan(1, 0, 0);
using (var serviceProxy = new CrmServiceClient(arguments.Connection))
{
- if (serviceProxy.OrganizationServiceProxy == null)
+ if (!serviceProxy.IsReady)
{
- throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.AUTH_ERROR, String.Format("Error connecting to the Organization Service Proxy: {0}", serviceProxy.LastCrmError));
+ throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.AUTH_ERROR, String.Format("Error connecting to the Organization Service: {0}", serviceProxy.LastCrmError));
}
- serviceProxy.OrganizationServiceProxy.Timeout = new TimeSpan(1, 0, 0);
if (!serviceProxy.IsReady)
{
trace.WriteLine("Not Ready {0} {1}", serviceProxy.LastCrmError, serviceProxy.LastCrmException);
@@ -196,7 +217,6 @@ private static void Run(CommandLineArgs arguments)
Console.WriteLine(exception.ArgumentHelp.Message);
Console.WriteLine(exception.ArgumentHelp.GetHelpText(Console.BufferWidth));
}
-
}
private static string BuildConnectionString(ServerConnection.Configuration config)
@@ -211,7 +231,7 @@ private static string BuildConnectionString(ServerConnection.Configuration confi
// AuthType=AD;Url=http://contoso:8080/Test; Domain=CONTOSO; Username=jsmith; Password=passcode
- // Office 365
+ // Office 365
// AuthType = Office365; Username = jsmith@contoso.onmicrosoft.com; Password = passcode; Url = https://contoso.crm.dynamics.com
// IFD
@@ -223,6 +243,7 @@ private static string BuildConnectionString(ServerConnection.Configuration confi
connectionString = String.Format("AuthType=AD;Url={0}", config.OrganizationUri);
break;
+
case AuthenticationProviderType.Federation:
connectionString = String.Format("AuthType=IFD;Url={0}", config.OrganizationUri);
break;
@@ -282,7 +303,6 @@ private static void RunTask(CommandLineArgs arguments, IOrganizationService serv
{
if (arguments.Path == null)
{
-
arguments.Path = Directory.GetCurrentDirectory();
}
else
@@ -291,11 +311,17 @@ private static void RunTask(CommandLineArgs arguments, IOrganizationService serv
arguments.Path = arguments.Path.TrimEnd('\\');
arguments.Path = Path.Combine(Directory.GetCurrentDirectory(), arguments.Path);
}
-
+
BaseTask task = null;
string command = arguments.Task.ToLower();
switch (command)
{
+ case "whoami":
+ trace.WriteLine("Who Am I?");
+ var whoAmIResponse = service.Execute(new WhoAmIRequest()) as WhoAmIResponse;
+ Console.WriteLine($"OrgId:'{whoAmIResponse.OrganizationId}' UserId:'{whoAmIResponse.UserId}'");
+ return;
+
case "plugins":
trace.WriteLine("Deploying Plugins");
task = new DeployPluginsTask(service, trace)
@@ -328,36 +354,49 @@ private static void RunTask(CommandLineArgs arguments, IOrganizationService serv
task = new DownloadWebresourceConfigTask(service, trace);
task.Prefix = arguments.Prefix;
break;
+
case "earlybound":
trace.WriteLine("Generating early bound types");
var earlyBound = new EarlyBoundClassGeneratorTask(service, trace);
task = earlyBound;
earlyBound.ConectionString = arguments.Connection;
break;
+
case "unpack":
trace.WriteLine("Unpacking solution");
var packager = new SolutionPackagerTask(service, trace);
packager.command = command;
task = packager;
break;
+
case "unpacksolution":
trace.WriteLine("Unpacking solution Zip");
var unpackfromsolution = new SolutionPackagerTask(service, trace);
unpackfromsolution.command = command;
task = unpackfromsolution;
break;
+
case "pack":
trace.WriteLine("Packing Solution");
var pack = new SolutionPackagerTask(service, trace);
pack.command = command;
task = pack;
break;
+
case "import":
trace.WriteLine("Packing & Import Solution");
var import = new SolutionPackagerTask(service, trace);
import.command = command;
task = import;
break;
+
+ case "export":
+ trace.WriteLine("Exporting Solution");
+ var export = new SolutionPackagerTask(service, trace);
+ export.command = command;
+ task = export;
+ break;
+
case "compare":
trace.WriteLine("Comparing Solution");
var compare = new SolutionPackagerTask(service, trace);
@@ -366,7 +405,6 @@ private static void RunTask(CommandLineArgs arguments, IOrganizationService serv
break;
}
-
if (task != null)
{
if (arguments.Profile != null)
@@ -374,7 +412,7 @@ private static void RunTask(CommandLineArgs arguments, IOrganizationService serv
task.Execute(arguments.Path);
}
else
- throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.NO_TASK_SUPPLIED, String.Format("Task '{0}' not recognised. Please consult help!", arguments.Task.ToLower()));
+ throw new SparkleTaskException(SparkleTaskException.ExceptionTypes.NO_TASK_SUPPLIED, String.Format("Task '{0}' not recognised. Please consult help!", arguments.Task.ToLower()));
}
}
-}
+}
\ No newline at end of file
diff --git a/spkl/spkl/XrmToolingCmdLine/SavedConnection.cs b/spkl/spkl/XrmToolingCmdLine/SavedConnection.cs
new file mode 100644
index 00000000..eb71537c
--- /dev/null
+++ b/spkl/spkl/XrmToolingCmdLine/SavedConnection.cs
@@ -0,0 +1,9 @@
+namespace SparkleXrmTask.XrmToolingCmdLine
+{
+ public class SavedConnection
+ {
+ public string EnvironmentUrl;
+ public string UserName;
+ public string DisplayName;
+ }
+}
\ No newline at end of file
diff --git a/spkl/spkl/XrmToolingCmdLine/XrmToolingConnection.cs b/spkl/spkl/XrmToolingCmdLine/XrmToolingConnection.cs
new file mode 100644
index 00000000..abf3901b
--- /dev/null
+++ b/spkl/spkl/XrmToolingCmdLine/XrmToolingConnection.cs
@@ -0,0 +1,173 @@
+using Microsoft.Xrm.Tooling.Connector;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.Linq;
+
+namespace SparkleXrmTask.XrmToolingCmdLine
+{
+ public class XrmToolingConnection
+ {
+ ///
+ /// Connection configurations - no credentials or tokens are stored here
+ ///
+ public static readonly string ConnectionsFilePath = Path.Combine(
+ Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "spkl"),
+ "Connections.json");
+
+ ///
+ /// Token Cache is used to store the Xrm Tooling tokens so user is not always prompted to login where possible
+ ///
+ public static readonly string TokenPath = Path.Combine(
+ Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "spkl"),
+ "TokenCache");
+
+ public string ConnectionString { get; internal set; }
+ private List _savedConnections = new List();
+
+ public XrmToolingConnection()
+ {
+ LoadSettings();
+ }
+
+ public CrmServiceClient Connect()
+ {
+ Console.ForegroundColor = ConsoleColor.Blue;
+ Console.WriteLine("Office365 Login");
+ Console.ForegroundColor = ConsoleColor.Cyan;
+ Console.WriteLine("Note: Use /l switch for on-premises or legacy login");
+ Console.ForegroundColor = ConsoleColor.Gray;
+
+ var connectionStringRoot = $@"AuthType=OAuth;
+ AppId=51f81489-12ee-4a9e-aaae-a2591f45987d;
+ RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97;
+ TokenCacheStorePath={XrmToolingConnection.TokenPath}";
+
+ // Show list of saved connections
+ // We don't store the credentials but instead use the Xrm.Tooling token cache
+ var configNumber = -1;
+ if (_savedConnections.Count > 0)
+ {
+ var i = 1;
+ Console.WriteLine("(0) Add New Server Configuration");
+ foreach (SavedConnection connection in _savedConnections)
+ {
+ Console.WriteLine($"({i}) {connection.EnvironmentUrl}, {connection.DisplayName}, {connection.UserName}");
+ i++;
+ }
+
+ Console.Write($"\nSpecify the saved server configuration number (0-{_savedConnections.Count}) [{_savedConnections.Count}] : ");
+ var input = Console.ReadLine();
+ Console.WriteLine();
+ if (input == string.Empty)
+ {
+ input = _savedConnections.Count.ToString();
+ }
+
+ if (!int.TryParse(input, out configNumber))
+ {
+ configNumber = -1;
+ }
+ }
+
+ SavedConnection selectedConnection;
+ var loginPrompt = "Auto";
+ var newConnection = configNumber <= 0;
+ if (newConnection)
+ {
+ selectedConnection = new SavedConnection();
+ var envUrl = ReadLine("Environment/Organization Url (e.g. org123.crm.dynamics.com)", regex: @"^(? c.EnvironmentUrl.Equals(selectedConnection.EnvironmentUrl, StringComparison.InvariantCultureIgnoreCase) &&
+ c.UserName.Equals(selectedConnection.UserName, StringComparison.InvariantCultureIgnoreCase));
+ _savedConnections.Add(selectedConnection);
+ SaveSettings();
+ }
+ this.ConnectionString = connectionString;
+ return client;
+ }
+ else
+ {
+ throw new Exception($"Cannot connect: {client.LastCrmError}", client.LastCrmException);
+ }
+ }
+
+ private void LoadSettings()
+ {
+ if (File.Exists(XrmToolingConnection.ConnectionsFilePath))
+ {
+ string configJson = File.ReadAllText(XrmToolingConnection.ConnectionsFilePath);
+ _savedConnections = JsonConvert.DeserializeObject>(configJson);
+ }
+ }
+
+ private void SaveSettings()
+ {
+ string configJson = JsonConvert.SerializeObject(_savedConnections);
+ File.WriteAllText(XrmToolingConnection.ConnectionsFilePath, configJson);
+ }
+
+ private string ReadLine(string prompt, string regex = null, string defaultValue = null)
+ {
+ if (defaultValue != null)
+ {
+ prompt += $"[{defaultValue}]";
+ }
+
+ bool isValid = true;
+ string returnedValue = defaultValue;
+ do
+ {
+ Console.Write(prompt + ": ");
+ string input = Console.ReadLine();
+ if (input.Length > 0)
+ {
+ if (regex != null && Regex.IsMatch(input, regex))
+ {
+ returnedValue = input;
+ isValid = true;
+ }
+ else
+ {
+ Console.WriteLine("\nInput invalid");
+ isValid = false;
+ }
+ }
+ else if (defaultValue == null)
+ {
+ Console.WriteLine("\nInput Required");
+ isValid = false;
+ }
+ } while (!isValid);
+ Console.Write("\n");
+ return returnedValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/spkl/spkl/packages.config b/spkl/spkl/packages.config
index 157c3ce5..1d8dc83f 100644
--- a/spkl/spkl/packages.config
+++ b/spkl/spkl/packages.config
@@ -1,18 +1,24 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
\ No newline at end of file
diff --git a/spkl/spkl/spkl.csproj b/spkl/spkl/spkl.csproj
index 984776fe..d652530d 100644
--- a/spkl/spkl/spkl.csproj
+++ b/spkl/spkl/spkl.csproj
@@ -39,66 +39,82 @@
True
- False
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Crm.Sdk.Proxy.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Crm.Sdk.Proxy.dll
True
-
- False
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
- True
+
+ ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
-
- False
- ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Rest.ClientRuntime.dll
True
- False
- ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.dll
+ ..\packages\Microsoft.CrmSdk.CoreAssemblies.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.dll
True
- ..\packages\Microsoft.CrmSdk.Deployment.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Deployment.dll
+ ..\packages\Microsoft.CrmSdk.Deployment.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Deployment.dll
True
- False
- ..\packages\Microsoft.CrmSdk.Workflow.9.0.0.7\lib\net452\Microsoft.Xrm.Sdk.Workflow.dll
+ ..\packages\Microsoft.CrmSdk.Workflow.9.0.2.23\lib\net462\Microsoft.Xrm.Sdk.Workflow.dll
True
-
- ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.0.0.7\lib\net452\Microsoft.Xrm.Tooling.Connector.dll
+
+ ..\packages\Microsoft.CrmSdk.XrmTooling.CoreAssembly.9.1.0.38\lib\net462\Microsoft.Xrm.Tooling.Connector.dll
True
+
+ ..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll
+
-
- ..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
- True
+
+ ..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll
+
+
+ ..\packages\System.Collections.Immutable.1.7.0\lib\netstandard2.0\System.Collections.Immutable.dll
+
-
- ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
- True
+
+ ..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll
+
+
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
-
- ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll
+ True
True
-
- ..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll
+ True
+ True
- ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net461\System.Security.Cryptography.Algorithms.dll
+ True
+ True
..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
@@ -106,13 +122,16 @@
..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
-
- ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
+ True
+ True
+
@@ -129,6 +148,8 @@
+
+
@@ -136,6 +157,7 @@
+
@@ -172,16 +194,25 @@
+
+
+
+
+
+
+
+
+