locked
transacted stream changes

    Question

  • Hello guys.

    According to the docs, there have been some changes in the way we write to a file. I update my old  demo code which now looks like this:

    app.onactivated = function (eventObject) {
            var local = Windows.Storage.ApplicationData.current.localFolder;
            var r = null;        
            local.createFileAsync("teste.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
                .then(function (file) {
                    return file.openTransactedWriteAsync();
                })
                .then(function (fileStream) {
                    var outputStream = fileStream.stream;
                    var writer = new Windows.Storage.Streams.DataWriter(outputStream);
                    writer.writeString("Olá mundo!");
                    return writer.storeAsync()
                        .then(function () {
                            return fileStream.commitAsync()
                                .then(function () {
                                    return fileStream.close();
                                })
                            .then(function () {
                                return outputStream.close();
                            });
                        });
                })
                /*
                .then(function (file) {
                    return Windows.Storage.FileIO.writeTextAsync(file, "Olá mundo!!");
                })*/
                .then(function (item) {
                    return local.getFileAsync("teste.txt");
                })
            .done(function (file) {
                Windows.System.Launcher.launchFileAsync(file)
            });

        };

    In the previous release, everything would work out great and notepad would get launched for showing the contents of the file. In this last release, in order to see notepad, I need to resort to setTimeout like this:

    setTimeout(function () {
                    Windows.System.Launcher.launchFileAsync(file);
                }, 500);

    Am I forgetting to clean everything in my code before launching notepad? I mean, I've looked at the sequence and it looks ok, but I probably need a new pair of fresh eyes to help me with this :)

    PS: I've just noticed that changing my code to use the FileIO.writeTextAsync does open the notepad without using the setInterval method, which probably means I'm really missing something in my code. can anyone see what?

    thanks.


    Luis Abreu


    Friday, June 8, 2012 2:21 PM

Answers

  • Possibly.

    Earlier, I tried the timer trick which seemed to work also.  But when I closed VS and launched the app from the Start page, it did not.  So, there are certainly things going on here that I don't understand.

    I also experienced a strange 'file not found' runtime exception that seemed to happen only on the first time the code was run in VS after an edit.  I would break, stop and rerun and things would be fine.

    • Marked as answer by Dino He Tuesday, June 26, 2012 9:02 AM
    Sunday, June 10, 2012 9:09 PM

All replies

  • bump?

    ok, a little more info. I've noticed that if I move the code to a button click (instead of running it from the activated event) it always works. is there some sort of race condition for my initial code?


    Luis Abreu


    Friday, June 8, 2012 8:15 PM
  • anyone? official comments? Hello? :)

    Luis Abreu

    Sunday, June 10, 2012 10:59 AM
  • Read the Remarks section here.

    "...make sure that you tie all file launches directly to the UI of your app. The user should always have to take some action to initiate a file launch."

    I think it is a security concern if your app just launches Notepad upon opening.  Executing the launch from a button click would be acceptable.

    The problem here may be related to the fact that your app has not completely rendered to the foreground before you are calling the launch function.  The delay trick gives the app time to become visible to the user.  Perhaps there is some event that would be more appropriate than the timer.  (Even then, it did not seem to work correctly when launched from the Start page without VS running.)  I think you need to use a button to ensure that the code executes on the UI thread.

    Other than that, I think your outputStream.close() is not needed since you are doing fileStream.close()



    • Edited by jrboddie Sunday, June 10, 2012 2:20 PM
    Sunday, June 10, 2012 1:44 PM
  • Hello.

    Hadn't noticed that remark. Thanks.

    but if that is correct, there's still a bug because I should never be able to open the file from the activated handler, right?

    btw, it works out when you use writeTextAsync instead of doing everything by hand like I did in the code I've shown...


    Luis Abreu

    Sunday, June 10, 2012 3:29 PM
  • Luis,

    I agree, that it should throw an access denied error if that were the problem.

    I restructured the code a bit to use chained promises because it is a little easier for me to read.  I am finding the writeTextAsync also does not work unless the module is executed from a button click event handler.

    Here is my example.  Here the onactivated event tries to execute the launch function.  You can also execute it with the button click.  In this version, I am using the writeTextAsync function.

        WinJS.Utilities.ready(function () {
            document.getElementById("doIt").addEventListener('click', launch, false);
        });
        app.onactivated = function (args) {
            launch();
         
        };
        function launch(){
            var fileName = "teste.txt"
            var fileStream;
            var local = Windows.Storage.ApplicationData.current.localFolder;
            local.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.replaceExisting)
            .then(function (file) {
                return Windows.Storage.FileIO.writeTextAsync(file, "Olá mundo!!");
            //    return file.openTransactedWriteAsync();
            //}).then(function (transaction) {
            //    fileStream = transaction;
            //    var writer = new Windows.Storage.Streams.DataWriter(fileStream.stream);
            //    writer.writeString("Olá mundo!");
            //    return writer.storeAsync();
            //}).then(function () {
            //    return fileStream.commitAsync();
            //}).then(function () {
            //    return fileStream.close();
            }).then(function () {
                return local.getFileAsync(fileName);
            }).then(function (file) {
                return Windows.System.Launcher.launchFileAsync(file);         
            }).done(function () {
                console.log('done');
            }, function (evt) {
                console.log('error ' + evt);
            });
        }


    • Edited by jrboddie Sunday, June 10, 2012 4:10 PM
    Sunday, June 10, 2012 4:08 PM
  • Hello again.

    I don't have the code here with me, but I'm almost positive that it opened the damn file at work...oh well...


    Luis Abreu

    Sunday, June 10, 2012 8:45 PM
  • Possibly.

    Earlier, I tried the timer trick which seemed to work also.  But when I closed VS and launched the app from the Start page, it did not.  So, there are certainly things going on here that I don't understand.

    I also experienced a strange 'file not found' runtime exception that seemed to happen only on the first time the code was run in VS after an edit.  I would break, stop and rerun and things would be fine.

    • Marked as answer by Dino He Tuesday, June 26, 2012 9:02 AM
    Sunday, June 10, 2012 9:09 PM
  • hum...it really looks like something is not entirely right here...I'll try to run my code again and I'll report back here.

    Luis Abreu

    Monday, June 11, 2012 9:12 AM
  • Any news? I have a similar problem. The launcher only works in response to a button click, but I want to launch the file on page load. Is this just no possible?
    Thursday, August 9, 2012 5:34 PM
  • I'm still waiting for an official on this too...

    Luis Abreu

    Tuesday, August 14, 2012 2:35 PM