Failing to save pdf from idw - autodesk-forge

Using Adams example from https://forge.autodesk.com/blog/store-template-documents-appbundle, i am trying to open an idw document and save as a pdf. I am getting the following error from forge
InventorCoreConsole.exe Information: 0 : Processing failed: System.Runtime.InteropServices.COMException (0x80004005): Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Inventor.TranslatorAddIn.SaveCopyAs(Object SourceObject, TranslationContext Context, NameValueMap Options, DataMedium TargetData)
at UpdateIPTParam.SampleAutomation.Run(Document doc) InventorCoreConsole.exe Error: 0 : Inventor message: Failed to publish DWF file. InventorCoreConsole.exe Error: 0 : Inventor inner xml:
code to open plugin
string idwDocPath = System.IO.Path.Combine(assemblyPath, parameters["generator"], "test.idw");
Document idwDoc = m_server.Documents.Open(idwDocPath, false);
pdf output code
TranslatorAddIn PDFAddIn;
TranslationContext context;
NameValueMap options;
DataMedium dataMedium;
GetPDFAddIn(m_server, out PDFAddIn, out context, out options, out dataMedium);
dataMedium.FileName = System.IO.Path.Combine(assemblyPath, parameters["generator"], "sampleOutput.pdf");
PDFAddIn.SaveCopyAs(idwDoc, context, options, dataMedium);
// Close the idw
idwDoc.Close(true);
void GetPDFAddIn(InventorServer ThisApplication, out TranslatorAddIn PDFAddIn, out TranslationContext context, out NameValueMap options, out DataMedium dataMedium)
{
PDFAddIn = (TranslatorAddIn)ThisApplication.ApplicationAddIns.ItemById["{0AC6FD96-2F4D-42CE-8BE0-8AEA580399E4}"];
context = ThisApplication.TransientObjects.CreateTranslationContext();
context.Type = IOMechanismEnum.kFileBrowseIOMechanism;
options = ThisApplication.TransientObjects.CreateNameValueMap();
options.Value["All_Color_AS_Black"] = 1;
options.Value["Remove_Line_Weights"] = 1;
options.Value["Vector_Resolution"] = 400;
options.Value["Sheet_Range"] = Inventor.PrintRangeEnum.kPrintAllSheets;
options.Value["Custom_Begin_Sheet"] = 1;
options.Value["Custom_End_Sheet"] = 1;
dataMedium = ThisApplication.TransientObjects.CreateDataMedium();
}
Any thoughts on why i would be getting this error?

Usually option settings is wrapped in if block.
// Check whether the translator has 'SaveCopyAs' options
if(PDFAddIn.HasSaveCopyAsOptions(oDocument, oContext, oOptions)){
// Options for drawings...
oOptions.Value["Sheet_Range"] = Inventor.PrintRangeEnum.kPrintCurrentSheet;
oOptions.Value["All_Color_AS_Black"] = 0;
// oOptions.Value["Remove_Line_Weights"] = 0;
// oOptions.Value["Vector_Resolution"] = 400;
// oOptions.Value["Custom_Begin_Sheet"] = 2;
// oOptions.Value["Custom_End_Sheet"] = 4;
}

Related

Design Automation API failing to open zip file

When I run a work item on the DA, I get the following reporting:
[07/24/2019 17:50:39] InventorCoreConsole.exe Information: 0 : Loading plug-in: iLogic Plugin
[07/24/2019 17:50:39] InventorCoreConsole.exe Information: 0 : Activating plug-in: iLogic Plugin
[07/24/2019 17:50:41] iLogic Plugin: initializing...
[07/24/2019 17:50:43] Unspecified error (Exception from HRESULT: 0x80004005 (E_FAIL))
[07/24/2019 17:50:43] InventorCoreConsole.exe Information: 0 : Opening document: T:\Aces\Jobs\66472a1ecb0f4612a610127e9e0ee497\Jet_Engine_Model.zip
[07/24/2019 17:50:43]
[07/24/2019 17:50:43] The process 1788 ended.
[07/24/2019 17:50:43] Process exit code: -1
[07/24/2019 17:50:44]
[07/24/2019 17:50:44] End Inventor Core Engine standard output dump.
[07/24/2019 17:50:44] Error: InventorCoreConsole.exe exits with code -1 which indicates an error.
[07/24/2019 17:50:44] End script phase.
[07/24/2019 17:50:44] Error: An unexpected error happened during phase CoreEngineExecution of job.
Usually, the error occurs after opening the zip file. I'm wondering if I'm specifying inputs incorrectly, or if the server is crashing because it's trying to run the iLogic plugin?
The following are the activity specs. Zip file is specified for input and output.
Activity activitySpec = new Activity()
{
Id = activityName,
Appbundles = new List<string>() { string.Format("{0}.{1}+{2}", NickName, appBundleName, Alias) },
CommandLine = new List<string>() { commandLine },
Engine = engineName,
Parameters = new Dictionary<string, Parameter>()
{
{ "inputFile", new Parameter() { Description = "input file", LocalName = "Jet_Engine_Model.zip", Ondemand = false, Required = true, Verb = Verb.Get, Zip = true } },
{ "inputJson", new Parameter() { Description = "input json", LocalName = "params.json", Ondemand = false, Required = false, Verb = Verb.Get, Zip = false } },
{ "outputFile", new Parameter() { Description = "output file", LocalName = "Jet_Engine_Model.zip", Ondemand = false, Required = true, Verb = Verb.Put, Zip = true } }
},
Settings = new Dictionary<string, ISetting>()
{
{ "script", new StringSetting(){ Value = engineAttributes.script } }
}
};
These are the workitem parameters. Are there any items that should be specified missing?
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
{
Verb = Verb.Get,
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, "Jet_Engine_Model.zip"),
Headers = new Dictionary<string, string>(){{ "Authorization", "Bearer " + oauth.access_token }}};
// 2. input json
dynamic inputJson = new JObject();
inputJson.length = lengthParam;
inputJson.numberOfFairings = fairingsParam;
XrefTreeArgument inputJsonArgument = new XrefTreeArgument(){
Verb = Verb.Get,
Url = "data:application/json, " + ((JObject)inputJson).ToString(Formatting.None).Replace("\"", "'")};
// 3. output file
//string outputFileNameOSS = string.Format("{0}_output_{1}",
DateTime.Now.ToString("yyyyMMddhhmmss"),
Path.GetFileName(input.inputFile.FileName)); // avoid overriding
XrefTreeArgument outputFileArgument = new XrefTreeArgument(){
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, "Jet_Engine_Model.zip"),
Verb = Verb.Put,
Headers = new Dictionary<string, string>(){{"Authorization", "Bearer " + oauth.access_token }}};
Thanks for your command line.
If I understand correctly you are trying to send zipped file which you would like to have unzipped before opening one of contained file in Inventor. In that case you have to specify name of contained file (because zip can contains more than one file). You can choose name of the file by adding attribute PathInZip to your inputFile argument in WorkItem definition. Like this:
XrefTreeArgument inputFileArgument = new XrefTreeArgument()
{
Verb = Verb.Get,
Url = string.Format("https://developer.api.autodesk.com/oss/v2/buckets/{0}/objects/{1}", bucketKey, "Jet_Engine_Model.zip"),
Headers = new Dictionary<string, string>(){{ "Authorization", "Bearer " + oauth.access_token }},
PathInZip = "FileNameInsideZip.ipt"
};

Downloading dwg to Forge

I'm in the process of learning the Forge platform. I'm currently using an example (Jigsawify) written by Kean Walmsley because it most accurately describes my goals. I'm running into an issue of getting my file to download from an Azure Storage Account to Forge. The error I receive is "The value for one of the HTTP headers is not in the correct format." My question is how does someone go about troubleshooting HTTP protocol when writing, in this case, a workitem in code? I can put in a breakpoint to view the workitem, but I'm not versed enough to understand where the flaw is in the HTTP header, or even where to find it. Is there a specific property of the workitem I should be looking at? If I could find the HTTP statement, I could test it, but I don't where I should find it.
Or am I just completely off base?
Anyway here's the code. It's a modified version of what Kean wrote:
static void SubmitWorkItem(Activity activity)
{
Console.WriteLine("Submitting workitem...");
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(Microsoft.Azure.CloudConfigurationManager.GetSetting("StorageConnectionString"));
StorageCredentials crd = storageAccount.Credentials;
CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
CloudFileShare ShareRef = fileClient.GetShareReference("000scrub");
CloudFileDirectory rootDir = ShareRef.GetRootDirectoryReference();
CloudFile Fileshare = rootDir.GetFileReference("3359fort.dwg");
// Create a workitem
var wi = new WorkItem()
{
Id = "", // Must be set to empty
Arguments = new Arguments(),
ActivityId = activity.Id
};
if (Fileshare.Exists())
{
wi.Arguments.InputArguments.Add(new Argument()
{
Name = "HostDwg", // Must match the input parameter in activity
Resource = Fileshare.Uri.ToString(),
StorageProvider = StorageProvider.Generic // Generic HTTP download (vs A360)
});
}
wi.Arguments.OutputArguments.Add(new Argument()
{
Name = "Results", // Must match the output parameter in activity
StorageProvider = StorageProvider.Generic, // Generic HTTP upload (vs A360)
HttpVerb = HttpVerbType.POST, // Use HTTP POST when delivering result
Resource = null, // Use storage provided by AutoCAD.IO
ResourceKind = ResourceKind.ZipPackage // Upload as zip to output dir
});
container.AddToWorkItems(wi);
container.SaveChanges();
// Polling loop
do
{
Console.WriteLine("Sleeping for 2 sec...");
System.Threading.Thread.Sleep(2000);
container.LoadProperty(wi, "Status"); // HTTP request is made here
Console.WriteLine("WorkItem status: {0}", wi.Status);
}
while (
wi.Status == ExecutionStatus.Pending ||
wi.Status == ExecutionStatus.InProgress
);
// Re-query the service so that we can look at the details provided
// by the service
container.MergeOption =
Microsoft.OData.Client.MergeOption.OverwriteChanges;
wi = container.WorkItems.ByKey(wi.Id).GetValue();
// Resource property of the output argument "Results" will have
// the output url
var url =
wi.Arguments.OutputArguments.First(
a => a.Name == "Results"
).Resource;
if (url != null)
DownloadToDocs(url, "SGA.zip");
// Download the status report
url = wi.StatusDetails.Report;
if (url != null)
DownloadToDocs(url, "SGA-Report.txt");
}
Any help is appreciated,
Chuck
Azure requires that you specify the x-ms-blob-type header when you upload to a presigned URL. See https://github.com/Autodesk-Forge/design.automation-.net-input.output.sample/blob/master/Program.cs#L167
So, I was able to figure out how to download my file from Azure to Forge using Albert's suggestion of moving to a blob service. Here's the code:
static void SubmitWorkItem(Activity activity)
{
Console.WriteLine("Submitting workitem...");
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(Microsoft.Azure.CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudBlobClient BlobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer cloudBlobContainer = BlobClient.GetContainerReference("000scrub");
CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference("3359fort.dwg");
// Create a workitem
var wi = new WorkItem()
{
Id = "", // Must be set to empty
Arguments = new Arguments(),
ActivityId = activity.Id
};
if (blockBlob.Exists())
{
wi.Arguments.InputArguments.Add(new Argument()
{
Name = "HostDwg", // Must match the input parameter in activity
Resource = blockBlob.Uri.ToString(),
StorageProvider = StorageProvider.Generic, // Generic HTTP download (vs A360)
Headers = new System.Collections.ObjectModel.ObservableCollection<Header>()
{
new Header() { Name = "x-ms-blob-type", Value = "BlockBlob" } // This is required for Azure.
}
});
}
wi.Arguments.OutputArguments.Add(new Argument()
{
Name = "Results", // Must match the output parameter in activity
StorageProvider = StorageProvider.Generic, // Generic HTTP upload (vs A360)
HttpVerb = HttpVerbType.POST, // Use HTTP POST when delivering result
Resource = null, // Use storage provided by AutoCAD.IO
ResourceKind = ResourceKind.ZipPackage, // Upload as zip to output dir
});
container.AddToWorkItems(wi);
container.SaveChanges();
// Polling loop
do
{
Console.WriteLine("Sleeping for 2 sec...");
System.Threading.Thread.Sleep(2000);
container.LoadProperty(wi, "Status"); // HTTP request is made here
Console.WriteLine("WorkItem status: {0}", wi.Status);
}
while (
wi.Status == ExecutionStatus.Pending ||
wi.Status == ExecutionStatus.InProgress
);
// Re-query the service so that we can look at the details provided
// by the service
container.MergeOption =
Microsoft.OData.Client.MergeOption.OverwriteChanges;
wi = container.WorkItems.ByKey(wi.Id).GetValue();
// Resource property of the output argument "Results" will have
// the output url
var url =
wi.Arguments.OutputArguments.First(
a => a.Name == "Results"
).Resource;
if (url != null)
DownloadToDocs(url, "SGA.zip");
// Download the status report
url = wi.StatusDetails.Report;
if (url != null)
DownloadToDocs(url, "SGA-Report.txt");
}
What isn't complete is the result section. The ZIP has nothing in it, but hey, baby steps right?
Thanks Albert.
-Chuck

Azure Stream Analytics Error : Could not deserialize the input event(s) from IOT hub

I have created the Stream Analytics job to read data from IOT hub as input and and to store data to SQL DB.
Here are the some important input details configured for Steam Analytics job are
Event Serialization format: JSON
Encoding :utf-8
The message is sent to IOT Hub from Dotnet simulated code.
When I am running my job I am getting the following error:
Could not deserialize the input event as Json. Some possible reasons:
1) Malformed events
2) Input source configured with incorrect serialization format
And here is the my dotnet code.
private static async void ReceiveC2dAsync()
{
Console.WriteLine("\nReceiving cloud to device messages from service");
while (true)
{
Message receivedMessage = await deviceClient.ReceiveAsync();
if (receivedMessage == null) continue;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received message: {0}", Encoding.ASCII.GetString(receivedMessage.GetBytes()));
Console.ResetColor();
await deviceClient.CompleteAsync(receivedMessage);
}
}
private static async void SendDeviceToCloudMessagesAsync()
{
double minTemperature = 20;
double minHumidity = 60;
int messageId = 1;
Random rand = new Random();
while (true)
{
double currentTemperature = minTemperature + rand.NextDouble() * 15;
double currentHumidity = minHumidity + rand.NextDouble() * 20;
var telemetryDataPoint = new
{
messageId = messageId++,
deviceId = "myFirstDevice",
temperature = currentTemperature,
humidity = currentHumidity
};
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
string levelValue;
string temperatureAlert = "false";
if (rand.NextDouble() > 0.7)
{
if (rand.NextDouble() > 0.5)
{
messageString = "This is a critical message";
levelValue = "critical";
}
else
{
messageString = "This is a storage message";
levelValue = "storage";
}
}
else
{
levelValue = "normal";
}
if(currentTemperature > 30)
{
temperatureAlert = "true";
}
var message = new Message(Encoding.UTF8.GetBytes(messageString));
message.Properties.Add("level", levelValue);
message.Properties.Add("temperatureAlert", temperatureAlert);
await deviceClient.SendEventAsync(message);
Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
await Task.Delay(1000);
}
}
it looks like your simulated device generated non-json formatted messages such as "This is a critical message" and "This is a storage message".
Basically, you have two choices to fix this issue:
1. comment this part in the simulated code or
2. add the filter in the Azure IoT Hub Routes for these messages

dlopen load library correct,but run the program,the result is incorrect

I use dlopen, dlsym load library function. When I run the program, I met this problem:
use dlopen load function, call the function correct but the result is incorrect
don't use dlopen and call the function directly,the result is correct
How can I find the problem?
Example:
void *dl_handle = NULL;
char *error = NULL;
/* Open the shared object */
dl_handle = dlopen(pLibraryName, RTLD_LAZY );
if (!dl_handle)
{
return -1
}
char* error = NULL;
pFunc = dlsym( dlHandle, "mysql_rollback");
error = dlerror();
if (error != NULL)\
{
return -1
}

Elmah and DbEntityValidationException

I have setup a project with both Elmah and EF4.1 Code First.
The project is throwing a System.Data.Entity.Validation.DbEntityValidationException, but Elmah is not providing enough detail to determine what validation is failing. All that is logged is:
System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Is there a way to make Elmah expand and log the EntityValidationErrors property?
List<IUserFeedback> errors = new List<IUserFeedback>();
try
{
_dbContext.SaveChanges();
Updated(this, HasUnsavedChanges);
}
catch (DbEntityValidationException ex)
{
foreach (var x in ex.EntityValidationErrors)
{
foreach (var y in x.ValidationErrors)
{
if (!String.IsNullOrWhiteSpace(y.PropertyName))
errors.Add(new UserFeedback() {
FeedbackFlags = TypeOfUserFeedbackFlags.Error,
Message = String.Format("Unable to save {0} due to an issue with its \"{1}\" value. The error returned was \"{2}\"",x.Entry.Entity, y.PropertyName, y.ErrorMessage)
});
else
errors.Add(new UserFeedback() {
FeedbackFlags = TypeOfUserFeedbackFlags.Error,
Message = String.Format("Unable to save {0} due to the error \"{1}\"", x.Entry, y.ErrorMessage)
});
}
}
}
return errors;