[c# COM CONNECT] save settings for file opened with OpenDesignFileForProgram

first this is a stand alone app so I have to use COM.

Maybe im missing something or misunderstanding this but I don't see how to do a save settings on a file that I opened via OpenDesignFileForProgram. I only found the key in but that wont work since its not the active file.

I see the save and saveas methods but I don't see a save settings. I see save settings at the application level. which only affects the active file. isn't save settings saving the design file settings. confused as to why its at the application level and not a method for the file.

Granted most of the things save settings does is GUI related so I see how opendesignfileforprogram wouldn't be the logical to use with save settings. but one of the things save settings does is associate the dgn file with the workspace/workset. which is what im trying to accomplish. since there is no COM call

im trying to get around the fact that DgnWorkSetInfo is not available in COM. and it just takes soo much longer to load the file to the screen (make active).  

Parents
  • Hi John,

    a few more notes in addition to Jon's answers:

    Maybe im missing something or misunderstanding this but I don't see how to do a save settings on a file that I opened via OpenDesignFileForProgram.

    There is no reason why there should be "save setting" feature available for OpenDesignFileForProgram method. These two "open methods" target different purposes and offer different set of features.

    Whereas normal open design file is backed by fully active MicroStation, open design file for program is more like "element stream" with only basic (typically elements related) functionality available. More complex concepts like rasters, references, views etc. do not exist in this approach.

    im trying to get around the fact that DgnWorkSetInfo is not available in COM

    Well, VBA / Interop API is pretty limited and is often the last updated in a chain C++ > NET > COM when a new feature is added to MicroStation.

    ill have to look into it some more and how to create one

    I agree with Jon that this is the way to go. I know about a few projects that quite quickly turned from limited Interop API to specifically designed initapp code that works as server communicating (e.g. using some RPC method) with client. An advantage is that in initapps, complete MicroStation API is available.

    I do not see it in CE examples, but there are V8i examples how to implement initapp in native code (which is the best way). I recommend to search also existing discussions, because how to use NET API was discussed also (e.g. here).

    With regards,

      Jan

    Answer Verified By: John Drsek 

  • thanks Jan, so if im understanding this right, its just an addin your loading on start up with the -wa parameter? 

    i was thinking it was some special kind of app. 

  • its just an addin your loading on start up with the -wa parameter? 

    i was thinking it was some special kind of app

    It is a special kind of app.  When you load something with the -wa switch, it is started before MicroStation's UI is initialised, and before any DGN file is opened.  The app must recognise its privileged status and act accordingly...

    • It can proceed to open DGN or other files and process them without showing any UI
    • It can choose to show MicroStation's UI
    • It can choose to show its own UI
    • It can choose to let MicroStation proceed normally, after doing whatever it needs to do

    AFAIK the only option for creating an MS_INITAPP for MicroStation CONNECT is to write a C++ app.  As I commented above, VBA can't do that.  I don't know whether a .NET AddIn can do it: I don't see any evidence that it can, but I'll be pleased to be shown otherwise.  A C++ app. can do it (I've written C++ several apps that are init apps).

     
    Regards, Jon Summers
    LA Solutions

  • Hi,

    It is possible use a C# Addins with MS_INITAPP

     protected override int Run( string[ ] commandLine )
     {
      if( commandLine.Contains( "MS_INITAPPS" ) )
      {
        // start a visible or invisble session
      }
     }

    In order to start a invisible Microstation, you have to open a designfile and then call mdlSystem_entergraphics via pinvoke if you want to use 'view' functionality.

     Utilities.ComApp.OpenDesignFile( dgnFilename, false, MsdV7Action.UpgradeToV8 );
     Utilities.ComApp.Visible = true;
     mdlSystem_enterGraphics( );

    To start a 'visible' Microstation, change the order of the methods above 

          Utilities.ComApp.Visible = true;
          mdlSystem_enterGraphics( );
          Utilities.ComApp.OpenDesignFile( dgn, false, MsdV7Action.UpgradeToV8 );
          
          .
          .
          .
        [DllImport( "ustation.dll", EntryPoint = "mdlSystem_enterGraphics", CallingConvention = CallingConvention.Cdecl )]
        public static extern int mdlSystem_enterGraphics( );

    Regards,

    Harmen

  • thanks Harmen,

    so i think im close. is there a way to not have the app be in the Mdlapps folder? is there a variable that controls this? im using the -WA parameter to kick it off. 

  • is there a way to not have the app be in the Mdlapps folder?

    MicroStation looks for apps in the folders listed in configuration variable MS_MDLAPPS.

     
    Regards, Jon Summers
    LA Solutions

  • thanks Jon,

    I must have fat fingered something because i did try that before posting. but tried it again and it worked.

  • i was able to get a simple c# MS_INITAPP to work. I was trying to see if i could not use COM but i couldn't find the quit in .net. 

    but i was able to open the file i wanted in .net and do what i needed. after i released i could get the worksetinfo from the dgnws file and apply it to the dgn file i was good.

    this code is assuming that the workspace name is passed (-WK), the workset name is passed (-WW) and i used some -i parameters to pass the files to process. 

    it will make sure the passed workset is the active workset. get the config variable to know where the dgnws file is. open the dgnws file and get the WorkSetInfo from it. now open the file that was passed and apply this worksetinfo to it. save and close. 

    protected override int Run(string[] commandLine)
            {
                try
                {
                    if (commandLine.Contains("MS_INITAPPS") || commandLine.Contains("-WA"))
                    {
                        string passedWorkSpaceName = "";
                        string passedWorkSetName = "";
                        List<string> filesToProcess = new List<string>();
    
                        foreach (string curCLP in commandLine)
                        {//get paramaters
                            if (curCLP.ToUpper().StartsWith("-WK"))
                            {
                                passedWorkSpaceName = curCLP.Trim().Remove(0, 3);
                            }
                            if (curCLP.ToUpper().StartsWith("-WW"))
                            {
                                passedWorkSetName = curCLP.Trim().Remove(0, 3);
                            }
                            if (curCLP.ToUpper().StartsWith("-IPATH"))
                            {
                                if (Directory.Exists(curCLP.Trim().Remove(0, 6)))
                                {
                                    string tempPath = curCLP.Trim().Remove(0, 6);
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.dgn", SearchOption.AllDirectories).ToList<string>());
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.cel", SearchOption.AllDirectories).ToList<string>());
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.dgnlib", SearchOption.AllDirectories).ToList<string>());
                                }
                            }
                            if (curCLP.ToUpper().StartsWith("-IFILE"))
                            {
                                if (File.Exists(curCLP.Trim().Remove(0, 6)) && (curCLP.ToUpper().EndsWith(".DGN") || curCLP.ToUpper().EndsWith(".CEL") || curCLP.ToUpper().EndsWith(".DGNLIB")))
                                {
                                    filesToProcess.Add(curCLP.Trim().Remove(0, 6));
                                }
                            }
                        }
                        if (filesToProcess.Count > 0)
                        {
                            if (passedWorkSetName != "" && passedWorkSpaceName != "")
                            {
                                if (Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSetName.ToUpper() == passedWorkSetName.ToUpper())
                                {//active workset/workspace match what was passed...means the desired workset was found
                                    //must set this to force the creation of the dgnws file if it does not exist
                                    Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSet = Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSet;
                                    //first get template worksetinfo
                                    BD.DgnWorkSetInfo SeedWorkSetInfo;
                                    string dgnwsFullPath = BD.ConfigurationManager.GetVariable("_USTN_WORKSETDGNWS");
                                    BD.DgnFileOwner DGNWSfileowner;
                                    BD.DgnFile DGNWSfile = null;
                                    BD.DgnDocument DGNWSDoc = BD.DgnDocument.CreateForLocalFile(dgnwsFullPath);
                                    DGNWSfileowner = BD.DgnFile.Create(DGNWSDoc, BD.DgnFileOpenMode.ReadOnly);
                                    DGNWSfile = DGNWSfileowner.DgnFile;
                                    BD.StatusInt openstatus;
                                    DGNWSfile.LoadDgnFile(out openstatus);
                                    if (openstatus == BD.StatusInt.Success)
                                    {
                                        SeedWorkSetInfo = BD.DgnWorkSetInfo.ExtractFromDgnFile(DGNWSfile);
                                        //close file
                                        DGNWSfile.Release();
                                        //loop files to process and assign workset 
                                        int counter = 0;
                                        //now open seed dgn file and apply this worksetinfo to it
                                        foreach (string curdgn in filesToProcess)
                                        {
                                            try
                                            {
                                                BD.DgnFileOwner fileowner;
                                                BD.DgnFile curfile = null;
                                                BD.DgnDocument dgndoc = BD.DgnDocument.CreateForLocalFile(curdgn);
                                                fileowner = BD.DgnFile.Create(dgndoc, BD.DgnFileOpenMode.ReadWrite);
                                                curfile = fileowner.DgnFile;
                                                curfile.LoadDgnFile(out openstatus);
                                                if (openstatus == BD.StatusInt.Success)
                                                {//opened file
                                                    SeedWorkSetInfo.Write(curfile);
                                                    BD.StatusInt result = curfile.ProcessChanges(BD.DgnSaveReason.FileClose);
                                                    if (result == BD.StatusInt.Success)
                                                    {//saved file
                                                     //close file
                                                        curfile.Release();
                                                        counter = counter + 1;
                                                    }
                                                    else
                                                    {//failed to save file
                                                     //close file
                                                        curfile.Release();
                                                    }
                                                }
                                                else
                                                {//failed to open file
                                                }
                                            }
                                            catch
                                            {//something went wrong processing this file..move on
                                            }
                                        }
                                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                        return counter;
                                    }
                                    else
                                    {//failed to open dgnws file
                                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                        return -5;
                                    }
                                }
                                else
                                {//active workset name does not match what was passed..failed to find desired workset
                                    Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                    return -4;
                                }
                            }
                            else
                            {//failed to get required command line parameters
                                Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                return -3;
                            }
                        }
                        else
                        {//no files to process
                            Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                            return 0;
                        }
                    }
                    else
                    {//not run as MS_INITAPPS
                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                        return -2;
                    }
                }
                catch
                {
                    Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                    return -1;
                }
            }

    i am calling up microstation from my stand alone app like this...

    Process P = new Process();
    P.StartInfo.FileName = MSCexePath;
    P.StartInfo.Arguments = "\"-WK" + WorkSpaceName + "\" \"-WW" + projName + "\" -WAOHDOTAssignWorksettoSeed \"-IPATH" + DestinationPath + "\\990-WorkSetStandards\\Seed\\\"";
    P.Start();
    P.WaitForExit();
    int result = P.ExitCode;

    ---UPDATE---

    looks like the return value in the run method of the addin MS_INITAPP is not being honored. it is always returning 0 as the exit code for that process. 

Reply
  • i was able to get a simple c# MS_INITAPP to work. I was trying to see if i could not use COM but i couldn't find the quit in .net. 

    but i was able to open the file i wanted in .net and do what i needed. after i released i could get the worksetinfo from the dgnws file and apply it to the dgn file i was good.

    this code is assuming that the workspace name is passed (-WK), the workset name is passed (-WW) and i used some -i parameters to pass the files to process. 

    it will make sure the passed workset is the active workset. get the config variable to know where the dgnws file is. open the dgnws file and get the WorkSetInfo from it. now open the file that was passed and apply this worksetinfo to it. save and close. 

    protected override int Run(string[] commandLine)
            {
                try
                {
                    if (commandLine.Contains("MS_INITAPPS") || commandLine.Contains("-WA"))
                    {
                        string passedWorkSpaceName = "";
                        string passedWorkSetName = "";
                        List<string> filesToProcess = new List<string>();
    
                        foreach (string curCLP in commandLine)
                        {//get paramaters
                            if (curCLP.ToUpper().StartsWith("-WK"))
                            {
                                passedWorkSpaceName = curCLP.Trim().Remove(0, 3);
                            }
                            if (curCLP.ToUpper().StartsWith("-WW"))
                            {
                                passedWorkSetName = curCLP.Trim().Remove(0, 3);
                            }
                            if (curCLP.ToUpper().StartsWith("-IPATH"))
                            {
                                if (Directory.Exists(curCLP.Trim().Remove(0, 6)))
                                {
                                    string tempPath = curCLP.Trim().Remove(0, 6);
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.dgn", SearchOption.AllDirectories).ToList<string>());
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.cel", SearchOption.AllDirectories).ToList<string>());
                                    filesToProcess.AddRange(Directory.GetFiles(tempPath, "*.dgnlib", SearchOption.AllDirectories).ToList<string>());
                                }
                            }
                            if (curCLP.ToUpper().StartsWith("-IFILE"))
                            {
                                if (File.Exists(curCLP.Trim().Remove(0, 6)) && (curCLP.ToUpper().EndsWith(".DGN") || curCLP.ToUpper().EndsWith(".CEL") || curCLP.ToUpper().EndsWith(".DGNLIB")))
                                {
                                    filesToProcess.Add(curCLP.Trim().Remove(0, 6));
                                }
                            }
                        }
                        if (filesToProcess.Count > 0)
                        {
                            if (passedWorkSetName != "" && passedWorkSpaceName != "")
                            {
                                if (Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSetName.ToUpper() == passedWorkSetName.ToUpper())
                                {//active workset/workspace match what was passed...means the desired workset was found
                                    //must set this to force the creation of the dgnws file if it does not exist
                                    Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSet = Bentley.MstnPlatformNET.Internal.WorkSpaceManager.ActiveWorkSet;
                                    //first get template worksetinfo
                                    BD.DgnWorkSetInfo SeedWorkSetInfo;
                                    string dgnwsFullPath = BD.ConfigurationManager.GetVariable("_USTN_WORKSETDGNWS");
                                    BD.DgnFileOwner DGNWSfileowner;
                                    BD.DgnFile DGNWSfile = null;
                                    BD.DgnDocument DGNWSDoc = BD.DgnDocument.CreateForLocalFile(dgnwsFullPath);
                                    DGNWSfileowner = BD.DgnFile.Create(DGNWSDoc, BD.DgnFileOpenMode.ReadOnly);
                                    DGNWSfile = DGNWSfileowner.DgnFile;
                                    BD.StatusInt openstatus;
                                    DGNWSfile.LoadDgnFile(out openstatus);
                                    if (openstatus == BD.StatusInt.Success)
                                    {
                                        SeedWorkSetInfo = BD.DgnWorkSetInfo.ExtractFromDgnFile(DGNWSfile);
                                        //close file
                                        DGNWSfile.Release();
                                        //loop files to process and assign workset 
                                        int counter = 0;
                                        //now open seed dgn file and apply this worksetinfo to it
                                        foreach (string curdgn in filesToProcess)
                                        {
                                            try
                                            {
                                                BD.DgnFileOwner fileowner;
                                                BD.DgnFile curfile = null;
                                                BD.DgnDocument dgndoc = BD.DgnDocument.CreateForLocalFile(curdgn);
                                                fileowner = BD.DgnFile.Create(dgndoc, BD.DgnFileOpenMode.ReadWrite);
                                                curfile = fileowner.DgnFile;
                                                curfile.LoadDgnFile(out openstatus);
                                                if (openstatus == BD.StatusInt.Success)
                                                {//opened file
                                                    SeedWorkSetInfo.Write(curfile);
                                                    BD.StatusInt result = curfile.ProcessChanges(BD.DgnSaveReason.FileClose);
                                                    if (result == BD.StatusInt.Success)
                                                    {//saved file
                                                     //close file
                                                        curfile.Release();
                                                        counter = counter + 1;
                                                    }
                                                    else
                                                    {//failed to save file
                                                     //close file
                                                        curfile.Release();
                                                    }
                                                }
                                                else
                                                {//failed to open file
                                                }
                                            }
                                            catch
                                            {//something went wrong processing this file..move on
                                            }
                                        }
                                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                        return counter;
                                    }
                                    else
                                    {//failed to open dgnws file
                                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                        return -5;
                                    }
                                }
                                else
                                {//active workset name does not match what was passed..failed to find desired workset
                                    Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                    return -4;
                                }
                            }
                            else
                            {//failed to get required command line parameters
                                Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                                return -3;
                            }
                        }
                        else
                        {//no files to process
                            Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                            return 0;
                        }
                    }
                    else
                    {//not run as MS_INITAPPS
                        Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                        return -2;
                    }
                }
                catch
                {
                    Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.Quit();
                    return -1;
                }
            }

    i am calling up microstation from my stand alone app like this...

    Process P = new Process();
    P.StartInfo.FileName = MSCexePath;
    P.StartInfo.Arguments = "\"-WK" + WorkSpaceName + "\" \"-WW" + projName + "\" -WAOHDOTAssignWorksettoSeed \"-IPATH" + DestinationPath + "\\990-WorkSetStandards\\Seed\\\"";
    P.Start();
    P.WaitForExit();
    int result = P.ExitCode;

    ---UPDATE---

    looks like the return value in the run method of the addin MS_INITAPP is not being honored. it is always returning 0 as the exit code for that process. 

Children
No Data