on 10-20-2014 1:25 PM
There is a convoluted way of doing so, described here: http://www.tek-tips.com/viewthread.cfm?qid=659152
I would like an easier way though. Enhancement request?? Or is it available programmatically so I could encapsulate in an user-defined DLL?
Why do I want this? Well it is terribly useful for troubleshooting to be able to see if a printout was created by an outdated rpt.
Message was edited by: Don Williams
So, I'm not sure about what was suggested there. But see this KBA:
1392793 - How to retrieve Crystal report version information using Visual Studio .NET?
- Ludek
Senior Support Engineer AGS Product Support, Global Support Center Canada
Follow us on Twitter
Message was edited by: Don Williams
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sorry. I managed to mangle the link pasting. Please remove the extraneous HTTP://
But basically the article describes a way whereby you create a subreport against the file system, filter on your report, and list the internal version as it is accessible as a variable this way.
I tested it and it works, but I do not know how much overhead it adds..
So, to get this we need to use the Inproc RAS API, which means we need to enter an OEM agreement with SAP? What does that cost and who do we contact? Does a mail to technologypartner@businessobjects.com suffice?
Hi Anders,
I fixed your link...
No need to be an OEM for an Enhancement request.
See the MS MSDN help file on that property:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa380376(v=vs.85).aspx
UFL would be the easiest way to implement this yourself.
Don
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Well. I have located it in the file. The info is stored as records with 0x1E in between. The actual strings are stored preceeded by a byte that is the string length + 1.
Not sure what you mean by "That number is saved as part of the files system and a property of the file" that would inply that it would be visible if you hit properties on the file, but it is not.
I have always had the impression that Windows is oblivious of the CR version number. The windows installer cannot read it for instance.
Edit: OK. Now I see the picture... But I do not see that info. How did you get that dialog?
Edit:2 I guess you mean propwerty sets of storage files? Let me dig into that..
OK. Basically this, need to put into an UFL, but how do you read the name of the file from an UFL or do you simply call it with the name and grab that from the predefined parameters?
// Reads the internal CR Revision number from File into Return
void CCRRevision::GetRevision(CString File, CString &Return)
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379016(v=vs.85).aspx
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa380376(v=vs.85).aspx
// http://forums.asp.net/t/966345.aspx?Problem+with+C+Class
HRESULT hr = S_OK;
IPropertySetStorage* pPropSetStg = 0;
IPropertyStorage* pPropStg = NULL;
// Open the root storage.
try
{
StgOpenStorageEx(File, STGM_READ | STGM_SHARE_DENY_WRITE, STGFMT_ANY,0, NULL, NULL, __uuidof(pPropSetStg), (void**)&pPropSetStg);
if (pPropSetStg == NULL) return;
pPropSetStg->Open(FMTID_SummaryInformation, STGM_READ | STGM_SHARE_EXCLUSIVE, &pPropStg);
// Read property using the ReadMultiple. This method takes a PROPVARIANT which is an extension of VARIANT.
PROPVARIANT pvar;
PROPSPEC propspec;
// Indicate that we want to access the property by ID rather than through its name
propspec.ulKind = 1;
PropVariantInit(&pvar);
propspec.propid = PIDSI_REVNUMBER;
pPropStg->ReadMultiple(1, &propspec, &pvar);
// For decisions and revisions which a minute will reverse.
Return = pvar.pszVal;
PropVariantClear(&pvar);
}
catch(...)
{
}
if (pPropStg != 0) pPropStg->Release();
if (pPropSetStg != 0) pPropSetStg->Release();
return;
}
OK. UFL done. You need to open differently:
hr = StgOpenStorageEx(wcstring, STGM_DIRECT_SWMR | STGM_READ | STGM_SHARE_DENY_NONE, STGFMT_ANY,0, NULL, NULL, ProviderGuid, (void**)&pPropSetStg);
As the file is already opened, also, the resulting DLL is kind of large (7M compared to my others that are around 20k) as it needs to duplicate all the COM stuff that already exists in CR. It works well though. Just add a variable with a formula of "CRRevision (Filename)" to have the internal versionnumber visible.
Still wish this was a standard function though.
Hi Anders,
You have been busy....
I heard back from the Product/Dev Owner last night and he's sent the request off to a Developer to look into adding it in the list of Special functions, where all of the other info from that TAB is.
One question, in CR Designer it auto increments when the report is saved. So in the SDK you'll be able to get the value also. Would you like to be able to increment the value also, it should not be able to decrement or set it to any value, increment only? Or simply leave it up to the engine to do this when ONLY using the SaveAs() API?
It may only be we can add the API as a read only property, which is the easiest to do. So depending on the work load that may be all we get but we can put it on the wish list for the SaveAs() increment.
Thanks again
Don
Let me explain why I dug into this... It has actually been in the back of my head for a long time, pretty much for the same reasons, but the "trigger" in this case was a case when the printed payslips were OK, but the emailed ones had incorrect info. They are all created from the same .rpt and the same code. Eventually, the user (everything would be so much easier without users..) felt it appropriate to tell me (finally) that they were created on two different PCs...
I checked and .rpt file on both and found that the incorrect one had a later modify date than the correct file, but an internal version that was some 40 increments behind the correct file.
Had I had this info on the actual printout, in 6pt text, vertically aligned to the left margin. The difference would have been immediately noticed. The error was a bug in a formula in a subreport.
So, for me, the Revision number as a read-only property would work perfectly.
Hi Anders
The KBAs take 48+ hours to replicate from the time of creation (just an FYI on the process we all have to put up with ). Anyhow, the KBA was replicated over the weekend and the link is the usual million miles long URL for KBAs.
- Ludek
KBA should be available now. It has the code you need to add to your app.
To add it to your report you could insert a text box and put the value into it using RAS or you could right a UFL to get the number using the SDK and insert that into a formula.
It will require distributing the .NET SDK SP13 though...
Thanks again
Don
OK. I downloaded SP14 (32 bit msi) and installed on my development machine. It still flags m_Report->SummaryInfo->RevisionNumber; as invalid, claiming that SummaryInfo has no such member. I tried specifying either:
#using <CrystalDecisions.CrystalReports.Engine.dll>
or
#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine\13.0.2000.0__692fbea5521e1304\CrystalDecisions.CrystalReports.Engine.dll>
Is there anything else I need to do?
edit:
OK. It still references the old dll, but why Xi? I never installed Xi on this machine...
Assembly crystaldecisions.crystalreports.engine
Member of Custom Component Set
c:\program files (x86)\sap businessobjects\crystal reports for .net framework 4.0\common\sap businessobjects enterprise xi 4.0\win32_x86\dotnet\crystaldecisions.crystalreports.engine.dll
Edit: Uninstalled everything but the full SAP Crystal Reports 2013 that I have, reinstelled CRVS runtime. I still have to have this ugly #uses:
#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.Shared\13.0.2000.0__692fbea5521e1304\CrystalDecisions.Shared.dll>
#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.Windows.Forms\13.0.2000.0__692fbea5521e1304\CrystalDecisions.Windows.Forms.dll>
#using <C:\Windows\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine\13.0.2000.0__692fbea5521e1304\CrystalDecisions.CrystalReports.Engine.dll>
Wrong, Do not install the runtime on your DEV PC. Uninstall it and use the first link to integrate into VS, when adding CR assemblies do not use the Browse button, use the .NET tab when adding assemblies. Runtime and CR for VS installer will not update each other and will overwrite the runtime so you may be mixing versions.
All you should see in the of what is installed on your DEV PC is this ( note I am using a beta of SP 15 😞
Download my test app for printing in KBA 2133438 and run it. It also uses the same API's to get the history.
See if that works after cleaning up your DEV PC runtimes.
Don
OK. Apparently did I misread the docs. I have followed yor advice, but cannot find KBA 2133438?
This is what I have now:
I took out the annoying paths so that the code again reads:
#using <CrystalDecisions.Shared.dll>
#using <CrystalDecisions.Windows.Forms.dll>
#using <CrystalDecisions.CrystalReports.Engine.dll>
Cleaned the app and rebuilt it. App runs fine! Thanks! Can you please clarify what you mean by: "when adding CR assemblies do not use the Browse button, use the .NET tab when adding assemblies." I did neither (this is an C++ MFC app)
Doh, sorry Anders, typo, KBA is 2163438. I only missed by one key...
In VS when adding assemblies use the .NET tab and do not browse to the CR runtime files. .NET Tab loads them from the GAC:
To update you DEV PC us the first link on this page:
All others are for redist purposes ONLY. Do not install any of the Redist packages on your DEV PC. The installer will ask you if you want the 64 bit runtime, that is the only option.
Don
OK. Thanks. I have printed out the tutorial, seems like excellent stuff.
FWIW, I use VS 2012 and C++/MFC (Only printing is .NET), the operation to add references is sligthtly different from C#. I will include a screenshot in case it helps someone else. Also, it does not seem necessary to add references here, just adding #using to the code seems to be sufficient.
My app works just fine now. I would love to test your sample app, but I cannot find it. The page says: "NOTE: To run just the executable browse to this folder: \RAS2010_Printing\bin\Release and double click on RAS10_CSharp_Printers.exe" - Am I to assume that the "Installer into vs" installs it? I did search on my machine, but could not find it. I also opened up the installer archive, but could not find it. Just in case someone else needs it....
Also, DOC-7824 seems to have two links pointing to the same document. The headings "Basics" and "The basics" both point to DOC-57979.
Just nitpicks I greatly applaud your work putting this together.
Hi Anders,
Ah yes, good to know you are using C++. You have download the sample app attached to the KBA. It the last thing in the KBA:
Attachments
|
Don
User | Count |
---|---|
88 | |
23 | |
11 | |
9 | |
8 | |
5 | |
5 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.